Implementierung v. Software-Produktlinien - Einführung und Überblick

Ähnliche Dokumente
Softwareproduktlinien - Laufzeitvariabilität

Softwareproduktlinien - Versionsverwaltungs- und Buildsysteme

Implementierung v. Software-Produktlinien - Einführung und Überblick

Softwareproduktlinien Teil 1: Einführung und Überblick

Softwareproduktlinien Teil 4: Versionsverwaltungs- und Buildsysteme

Softwareproduktlinien - Entwicklungsprozess und Variabilitätsmodellierung

Softwareproduktlinien Teil 2: Entwicklungsprozess und Variabilitätsmodellierung

Software Product Lines

Erweiterte Programmierkonzepte für maßgeschneiderte Datenhaltung Teil 3: Software-Produktlinien

Software Product Lines

Softwareproduktlinien - Entwicklungsprozess und Variabilitätsmodellierung

Softwareproduktlinien Teil 1: Einführung und Überblick

Softwareproduktlinien Teil 2: Entwicklungsprozess und Variabilitätsmodellierung

Softwareproduktlinien Teil 11: Verbesserte Präprozessoren

Erweiterte Programmierkonzepte für maßgeschneiderte Datenhaltung. Teil 4. Frameworks

Softwareproduktlinien Teil 12: Analyse von Produktlinien

Erweiterte Programmierkonzepte für Maßgeschneiderteres Datenmanagement (EPMD) Teil 1: Einführung und Überblick

Creational Patterns. Seminar Software-Entwurf. Thomas Liro WS 2004/05.

Softwareproduktlinien - Analyse von Produktlinien

Einstieg in die Informatik mit Java

Softwaretechnik. Prof. Dr. Rainer Koschke. Fachbereich Mathematik und Informatik Arbeitsgruppe Softwaretechnik Universität Bremen

Softwaretechnik. Überblick I. Prof. Dr. Rainer Koschke. Sommersemester 2006

Softwareproduktlinien Teil 12: Analyse von Produktlinien. Christian Kästner (CMU) Sven Apel (Universität Passau) Gunter Saake (Universität Magdeburg)

Moderne Programmierparadigmen Objekt-Orientierung

Software Product Lines

Feature Modelle. und ihre Anwendung. Feature Modelle und ihre Anwendungen. Fachgebiet Softwaretechnik, Heinz Nixdorf Institut, Universität Paderborn

Entwicklungswerkzeuge

Anwendung der Aspektorientierung: Design Patterns

11. Komponenten Grundlagen der Programmierung 1 (Java)

Softwareproduktlinien Teil 12: Analyse von Produktlinien. Sven Apel (Universität Passau) Gunter Saake (Universität Magdeburg)

Tool-Chain. Übung. Eclipse, SVN, Ant, Cobertura, Metrics Labor "Software Engineering Experiment" Sebastian Meyer und Kai Stapel

Objektorientierte und Funktionale Programmierung SS 2014

Grundlagen der Programmierung Prof. H. Mössenböck. 15. Pakete

Design Patterns. 5. Juni 2013

Softwaretechnik. Überblick I. Prof. Dr. Rainer Koschke. Sommersemester 2009

Comparing Software Factories and Software Product Lines

Einführung in Generatives Programmieren. Bastian Molkenthin

Lehrstuhl für Datenverarbeitung. Technische Universität München. Grundkurs C++ Buildsysteme

Entwurfsmuster - Iterator & Composite

Vorlesung Programmieren

Decorator Pattern. Analyse- und Design-Pattern CAS SWE FS14. Roland Müller Samuel Schärer

Handbuch für die Erweiterbarkeit

Programmieren 2 Java Überblick

Generatives Programmieren

Daniel Warneke Ein Vortrag im Rahmen des Proseminars Software Pioneers

Softwarefamilien und Produktlinien - systematische Wiederverwendung - Matthias Clauß Intershop Research & TU Dresden

Übungen Softwaretechnik I

Softwareschnittstellen

Motivation Grundlagen Technologien Manipulation Ecore Genmodell Demo Persistenz Notification Ausblick GMF Fazit / Quellen

Graphische Benutzungsoberflächen mit Java. Einführung in NetBeans

C++ Templates - eine kleine Einführung. Funktionstemplates. Fabian Scheler, Peter Ulbrich, Niko Böhm. 20. Oktober 2008

Continuous Everything

Programmierung im Grossen

Webentwicklung mit Vaadin 7. Theoretische und praktische Einführung in Vaadin 7. Christian Dresen, Michael Gerdes, Sergej Schumilo

SODA. Die Datenbank als Document Store. Rainer Willems. Master Principal Sales Consultant Oracle Deutschland B.V. & Co. KG

Grundkurs C++ Buildsysteme Versionsverwaltung mit git

Software Engineering I

Interaktionen zwischen Objekten durch Senden von Nachrichten und Reagieren auf empfangene Nachrichten

Möglichkeiten der Maßschneiderung von DBMS

Software Engineering

Programmieren II. Innere Klassen. Heusch 10, Ratz 5.2.1, Institut für Angewandte Informatik

Software(technik)praktikum: SVN-Tutorial

Softwareproduktlinien - Refactoring von SPLs und ihren Produkten

Software Design basierend auf dem Plug-In Konzept

Design Patterns 2. Model-View-Controller in der Praxis

Einführung in die Programmierung mit Java

Analyse und Modellierung von Informationssystemen

Inhaltsverzeichnis. 2.2 Grundlagen der UML Zusammenfassung... 53

Analyse und Modellierung von Informationssystemen

Probeklausur: Programmierung WS04/05

Erste Erfahrungen mit NSASJ anhand der OmnivoBase Portierung. September 2013

TEIL I: OBJEKTORIENTIERUNG UND GRUNDKURS JAVA GRUNDLAGEN DER PROGRAMMIERUNG... 4

Software-Architektur Design Patterns

Repetitorium Informatik (Java)

Entwurfsprinzip. Entwurfsprinzip

Model-View-Controller

Informatik II Übung 6 Gruppe 7

Theorie zu Übung 8 Implementierung in Java

Schnittstellen, Stack und Queue

Feature-Komposition auf Bytecode-Ebene

Software Engineering in der Praxis

Rapid Java wie mit Forms

Spring Dynamic Modules for OSGi Service Platforms

Software-Entwurfsmuster

Softwareproduktlinien - Komponenten und Frameworks

UML-Basics: Einführung in Objekt- Orientierte Modellierung mit der Unified Modeling Language

FACHHOCHSCHULE MANNHEIM

Anwendungsentwicklung mit Java. Grundlagen der OOP, Vererbung, Schnittstellen, Polymorphie

Application Frameworks

Übersicht. Softwarearchitektur. Softwarearchitektur, UML, Design Patterns und Unit Tests. Softwarearchitektur

Inhaltsverzeichnis 1 Einführung Die Software JGIS Grundlagen raumbezogener Daten

Universität Stuttgart Institut für Automatisierungstechnik und Softwaresysteme Prof. Dr.-Ing. M. Weyrich

Konzepte von Betriebssystem-Komponenten. Programmstart & dynamische Bibliotheken SS 05. Wladislaw Eckhardt.

Design Pattern. Motivation, Beispiel Definition "Das" Buch der Gang of Four Ausführliches Beispiel: Facade Beispiele. Aufgabe

Einführung in die Informatik II

Entwurfsmuster Martin Fesser 00IN

Einstieg in die Informatik mit Java

wenige Konzepte, keine Adressen, Anlehnung an C++ -Syntax Vererbung, Polymorphie/dynamisches Binden, umfangreiche Klassenbibliotheken

Ein Erfahrungsbericht beim Einsatz von generierenden Ansätzen im Vergleich zu generischen Lösungen

Berichte aus der Informatik. Dieter Pawelczak. Start in die C-Programmierung

Transkript:

Implementierung v. Software-Produktlinien - Einführung und Überblick Christian Kästner (Carnegie Mellon University) Sven Apel (Universität Passau) Gunter Saake, Thomas Thüm (Universität Magdeburg) 1

Agenda Formales, Organisatorisches Kurzeinführung in das Themengebiet 2

3 Hintergrund

Industrielle Revolution 1980s Automatische Fließbänder (erster Industrieroboter 1961 bei General Motors) 1901 Fließband (Ransom Olds/Henry Ford) 1826 Austauschbare Teile (John Hall, nach 25 vergebl. Jahren) [Czarnecki & Eisenecker 2000] 4

Produktlinien in der Industrie 5

Auto-Produktlinie 6

Variantenvielfalt Varianten sind ein wesentlicher Hebel für das Unternehmensergebnis Franz Decker, Leiter Programm Variantenmanagement, BMW Group 7

PKW-Produktlinien vor 20 Jahren Auswahl beschränkte sich auf Autotyp und ggf. noch wenige Extras wie alternativer Kassettenrekorder oder Dachgepäckträger Eine Variante (Audi 80, 1.3l, 55PS) machte 40% des Umsatzes aus

PKW-Produktlinien vor wenigen Jahren 10 20 mögliche Varianten eines Audi; 10 32 mögliche Varianten eines BMW Kaum ein Auto verlässt das Werk identisch zu einem vorherigen Allein 100 verschiedene Bodengruppen für ein Modell, je nach Motor und Ausstattung 50 verschiedene Lenkräder (3 vs. 4 Speichen, Holz vs. Kunststoff vs. Leder, Heizung, Farben)

Weitere Produktlinien 10

Weitere Produktlinien 11

Weitere Produktlinien 12

Weitere Produktlinien

Massenproduktion 15

Und bei Software? Moderne Anwendungssoftwaresysteme sind Eier-legende Wollmilchsäue Bsp.: Windows Vista, Open Office, Oracle, SAP myerp, Adobe Photoshop, Nero Burning ROM Spezialisierte Software und Software für eingebettete Systeme wird immer wichtiger 16 Bsp.: PDA, Handy, Sensornetze, Mikrowelle, Fernseher, Wetterstation, Auto, Chipkarten, Bordcomputer, Router, Ubiquitious Computing 98% aller im Einsatz befindlichen Rechnersysteme sind eingebettete Systeme Ressourcenbeschränkung und heterogene Hardware erfordert maßgeschneiderte Lösungen Häufige Neuimplementierungen, lange Entwicklungszeiten, hohe Entwicklungskosten

Warum maßgeschneiderte Software? Personalisierung Individuelle Anforderungen, Look-and-Feel, Spezialalgorithmen, rechtlicher Rahmen, Hardware, Ressourcenbeschränkung Energieverbrauch, Performanz, Speicherverbrauch,. Software- und Produkt-Qualität Benutzbarkeit Ungenutzte Funktionalität als Risiko Wartungs- / Kontroll- / Testaufwand wächst mit Funktionsumfang Kosten, Aufwand, Flexibilität, Konkurrenz,

Features in Microsoft Office 18

Linux-Kernel ca. 6.000.000 Zeilen Quelltext Sehr weitgehend Konfigurierbar > 10.000 Konfigurationsoptionen! (x86, 64bit, ) Fast aller Quelltext ist optional

Datenbanken Ständig wachsendes Datenaufkommen Häufige Einbettung mit Ressourcenbeschränkungen 20

Drucker- Firmware

Spiele 22

Softwareproduktlinien in der Industrie HP: Druckertreiber/Firmware Nokia: Mobiltelefon-Software, Browser Phillips: High-End TVs, Medizintechnik, TomTom: eingebettete Navigationssysteme Cummins: Dieselmotoren-Steuerungssoftware LG: Aufzugsteuerungssoftware Ericsson: Telecommunication switches General Motors: Powertrains Viele weitere: Gasturbinen, train control, ship control, frequency converter, internet payment gateway, helicopter avionics software, 23

Ziel der Vorlesung Techniken für die Entwicklung maßgeschneiderter Software, die genau die benötigte Funktionalität enthält Varianten für verschiedene Anwendungsfälle Neue Varianten können leicht hinzugefügt werden; schnelle Entwicklung; Wiederverwendung bewährter Funktionalität Kundenindividuelle Fertigung; Spezialisierung Anpassung an verfügbare Ressourcen Softwareproduktlinien (SPL): Konfiguration durch Auswahl von Features (deutsch: Merkmale) 24

Schätzung Circa 80% aller Softwaresysteme sind Softwareproduktlinien bzw. können von Softwareproduktlinientechnologie profitieren. 25

26 Herausforderungen

Variabilität = Komplexität

33 optionale, unabhängige Features eine maßgechneiderte Variante für jeden Menschen auf dem Planten

320 optionale, unabhängige Features mehr Varianten als es Atome im Universum gibt!

Korrektheit?

Alle Kombinationen sinnvoll? 33

Wiederverwendung bei der Implementierung? Wo Fehler korrigieren?

Idee: Systematische Entwicklung von Softwareproduktlinien Jeweils neu programmieren ist sowohl unwirtschaftlich als auch gefährlich Daher maßgeschneiderte Software auf Basis von Softwareproduktlinien Aus wiederverwendbaren Teilen Die alternative Implementierungen haben können Anpassbar für spezielle Anwendungsfälle Nutzbar auch unter extremer Ressourcenbeschränkung

Entwurf und Implementierung von Features Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. Feature-Auswahl Generator Fertiges Program

Implementierung: State of the Art Wenn überhaupt Variantenmanagement, dann mit #ifdef, Templates, make, CVS Beispiel: Berkeley DB (mutex_int.h) #ifndef _DB_MUTEX_INT_H_ #define _DB_MUTEX_INT_H_ #ifdef HAVE_MUTEX_PTHREADS #include <pthread.h> #define #endif MUTEX_FIELDS pthread_mutex_t mutex; /* Mutex. */ pthread_cond_t cond; /* Condition variable. */ #ifdef HAVE_MUTEX_UI_THREADS #include <thread.h> #endif #ifdef HAVE_MUTEX_SOLARIS_LWP #include <synch.h> #define #endif MUTEX_FIELDS lwp_mutex_t mutex; /* Mutex. */ lwp_cond_t cond; /* Condition variable. */ #ifdef HAVE_MUTEX_UI_THREADS #include <thread.h> #include <synch.h> #define #endif MUTEX_FIELDS mutex_t mutex; /* Mutex. */ cond_t cond; /* Condition variable. */ #ifdef HAVE_MUTEX_AIX_CHECK_LOCK #include <sys/atomic_op.h> typedef int tsl_t; #ifdef LOAD_ACTUAL_MUTEX_CODE #define MUTEX_INIT(x) 0 #define MUTEX_SET(x) (!_check_lock(x, 0, 1)) #define MUTEX_UNSET(x) _clear_lock(x, 0) #endif #endif

Implementierung und Wartbarkeit? 40 class Stack { void push(object o #ifdef SYNC, Transaction txn #endif ) { if (o==null #ifdef SYNC txn==null #endif ) return; #ifdef SYNC Lock l=txn.lock(o); #endif elementdata[size++] = o; #ifdef SYNC l.unlock(); #endif firestackchanged();

SPL-Implementierung Verschiedene Wege SPLs zu implementieren In dieser Vorlesung betrachten wir u.a. Versionsverwaltungssysteme Präprozessoren Komponenten Frameworks/Plugins Feature-orientierte Programmierung Aspekt-orientierte Programmierung sowie weiterführende Themen Feature-Interaktionen Produktlinienanalyse 41 Refactorings

Wieviel Variabilität ist sinnvoll? Entwicklungskosten Investitionskosten Wartungskosten Logistikkosten Fertigungskosten (geringe Stückz.) 42

Schwerpunkte Maßgeschneiderte Software als Ziel Feature als zentrales Konzept Implementierung von Features steht im Vordergrund Viel Quelltext, diverse Paradigmen und Sprachen 43

1 Formales, Organisatorisches

Forschungsnahe Vorlesung Relativ junges Forschungsgebiet Vermittlung aktueller Forschungsergebnisse Literatur Begleitbuch Verschiedene weitere Bücher Konferenzpublikationen (meist Englisch) Aufgelistet jeweils am Ende eines Kapitels Viele Anknüpfungspunkte für eigene Forschungen z. B. Bachelor-, Masterarbeiten, Praktika, Seminare, Individualprojekte, Teamprojekte, Dissertationen, 2

Digitale Version über Universitätsbibliothek frei verfügbar

Erwartete Vorkenntnisse Grundlagen der Softwaretechnik (Modularität, Versionsverwaltung, Design Patterns, Entwicklungsprozess, ) Grundlagen der Objektorientierten Programmierung und Modellierung (UML) Grundkenntnisse Java 4

Vorlesung Dienstags 11:15 12:45 Uhr in G22A-210 Bachelor, Master (Diplom) 2-stündig, 5/6 CP Eine Gastvorlesung aus der Praxis (pure::systems) Anmeldung über LSF bis 26.10.2014 5

Übung Freitags 13:00 15:00 Uhr in G22A-113 Ab dem 24.10.2014 (nächste Woche) Votierungen Programmieraufgaben Programmiertechnik vorgegeben, Thema frei wählbar 1.-5. für Bachelor/Master, 6. nur für Master Fristgerechte Abgabe von eigenen Lösungen Wahlweise open source oder privates Git repository Teilnahme an wissenschaftlichem Experiment (max. 2h) 6

Prüfung und Schein Prüfungszulassung/Schein > 60 % Votierungen Programmieraufgaben Mündliche Prüfung Wenn Prüfungszulassung erreicht 20-30 Minuten 7

Softwareproduktlinien - Entwicklungsprozess und Variabilitätsmodellierung Sven Apel (Universität Passau) Christian Kästner (Universität Marburg) Gunter Saake, Thomas Thüm (Universität Magdeburg) 1

Agenda Produktlinien Was ist ein Feature? Domain Engineering vs. Application Engineering Feature-Modellierung 2

Produktlinien A software product line (SPL) is a set of software-intensive systems that share a common, managed set of features satisfying the specific needs of a particular market segment or mission and that are developed from a common set of core assets in a prescribed way. Software Engineering Institute Carnegie Mellon University 3

Produktlinien Eine Menge von Programmvarianten (Software- Produkten), teilen eine gemeinsame Menge von Merkmalen (Features)...die auf ein gemeinsames Marktsegment (Domäne) zugeschnitten sind...mit dem Ziel der Wiederverwendung von gemeinsamen Software-Artefakten z. B. Datenbank-Produktlinie für eingebettete Systeme 4

Domäne Die Produkte einer Produktlinie sind zugeschnitten auf ein Anwendungsgebiet Dieses Anwendungsgebiet wird als Domäne bezeichnet Horizontale Domänen Abrechnungen, Lagerverwaltung, Flugbuchung Vertikale Domänen Numerische Algorithmen, Netzwerktreiber, GUIs, Datenbanken 5

Was ist ein Feature? (deutsch Merkmal) Domänenabstraktion Features repräsentieren Anforderungen, Gemeinsamkeiten bzw. Unterschiede von Produktvarianten Mittel zur Kommunikation zwischen Stakeholdern Dient zur Spezifikation von Produktvarianten Feature-Auswahl als Eingabe für die Produktgenerierung Aber: es gibt auch Belange, die keine Features sind 6

Belang vs. Feature Belang (siehe spätere Kapitel) Jedwede Problemstellung, die von Interesse ist Feature Problemstellung, die eine besondere Bedeutung in einer Domäne hat Konfigurationsoption Belange Features 7

Features vs. Varianten Features sind Grundbausteine einer Produktlinie (z.b. implementiert durch Komponenten, Packages, etc.) Feature-Kombinationen bilden individuelle Produkte 8

Features in Datenbanken Transaktionsverwaltung Log & Recovery Schreibzugriff Persistenz / In-Memory Seitenverdrängungsstrategien LRU / LFU / Clock /... Sortierverfahren Datentypen variabler Länge Gruppieren, Aggregation Windows / Unix / NutOS / TinyOS / 9

Entwicklung einer Produktlinie Entwicklung einer Produktlinie statt einzelner Produkte Produktlinie deckt Anforderungen der ganzen Domäne ab Abweichung vom klassischen Entwicklungsprozess und Lebenszyklus Unterscheidung in Domain Engineering Application Engineering 10

Software Lebenszyklus Klassisch 11

Domain Engineering [...] is the activity of collecting, organizing, and storing past experience in building systems [...] in a particular domain in the form of reusable assets [...], as well as providing an adequate means for reusing these assets (i.e., retrieval, qualification, dissemination, adaptation, assembly, and so on) when building new systems. 12 K. Czarnecki and U. Eisenecker

Application and Domain Engineering 13

Entwicklungsaufwand Aufwand/Kosten Konventionelle Entwicklung Produktlinienentwicklung 1 2 3 4 # Produkte 14

Scoping Eingrenzung der Domäne Welche Features sind relevant/sollen entwickelt werden Oft wirtschaftliche Entscheidung [Schmid 2002] 15

Exkurs: Ansätze zur Einführung von Produktlinien Es gibt drei übliche Ansätze eine Softwareproduktlinie zu erstellen / den Ansatz einzuführen Proaktives Vorgehensmodell Reaktives Vorgehensmodell Extraktives Vorgehensmodell Für alle Implementierungstechniken Auswahl anhand betrieblicher Gesichtspunkte (Kosten, Risiko, Chancen,...) 16

Exkurs: Proaktives Vorgehensmodell Produktlinie neu entwerfen und implementieren; wie bisher besprochen Komplette Domänenanalyse zu Beginn Kann die normale Entwicklung für mehrere Monate unterbrechen, bis die Produktlinie auf dem Stand der bestehenden Produkte ist Hohe Kosten und hohes Risiko Gut wenn Anforderungen wohl-definiert sind 17

[Krueger 2002] 18

Exkurs: Reaktives Vorgehensmodell Analog zu Spiralmodell oder Extreme Programming Implementiert zuerst wenige Produktvarianten; fügt inkrementell weitere hinzu Geeignet, wenn benötigte Varianten nicht komplett im voraus bekannt, und für unvorhergesehene Änderungen Kleinere Projektgröße, geringere Anfangskosten; weniger Ressourcenbindung, schnellere Ergebnisse Später evtl. Umstrukturierungen nötig 19

[Krueger 2002] 20

Exkurs: Extraktives Vorgehensmodell Nutzt eine oder mehrere bestehende Produkte als Basis Extrahiert daraus Features und erlaubt so Produktvarianten zu erzeugen Geeignet für den schnellen Wechsel von traditionellen Anwendungen zu Produktlinien Relativ geringer Ressourcenaufwand und Risiko Sehr anspruchsvoll für Werkzeuge und Sprachen, da Zerlegung einer Anwendung, die nicht als Produktlinie entworfen wurde 21

[Krueger 2002] 22

Feature-Modellierung Beschreibung der Features einer Domäne Zur Visualisierung und Kommunikation Ein Feature-Modell beschreibt die elementaren Abstraktionen einer Domäne und deren Beziehungen die Menge der Produkte einer Produktlinie Ein Feature-Diagramm visualisiert Features und deren Beziehungen 23

Gültige Feature-Auswahl? Transaktionsverwaltung Log & Recovery Schreibzugriff Persistenz / In-Memory Seitenverdrängungsstrategien LRU / LFU / Clock /... Sortierverfahren Datentypen variabler Länge Gruppieren, Aggregation Windows / Unix / NutOS / TinyOS / 24

25

Feature-Modell: Beispiel Features: Basis, Txn, Write, Win, Unix Abhängigkeiten: Basis muss immer ausgewählt sein und braucht Win oder Unix Win darf nie zusammen mit Unix ausgewählt werden Wenn Txn ausgewählt ist muss auch Write ausgewählt sein Wieviele Varianten möglich? Sechs mögliche Varianten {Basis, Win, {Basis, Unix, {Basis, Win, Write, {Basis, Unix, Write, {Basis, Win, Write, Txn, {Basis, Unix, Write, Txn 26

Feature-Modell als aussagenlogischer Ausdruck Variable für jedes Feature (wahr wenn ausgewählt) Formel beschreibt Feature-Modell Formel wahr für gültige Feature-Auswahl Basis ( Unix Win) ( Unix Win) ( Txn Write) Erlaubt automatische Überprüfung, und Aufzählen der gültigen Produktvarianten (SAT, BDD, ) 27

Feature-Diagramm Graphische Darstellung, hierarchische Struktur Kinder: optional, obligatorisch, oder, alternativ Abstrakt vs konkret: ohne vs mit Bezug zur Implementierung Abstrakte Features haben keinen Einfluss auf Produkte optional abstrakt obligatorisch alternativ (genau 1) oder (min 1) 28 konkret

Beispiel: Sternenflotten-Produktlinie Officer Hair Gender Body

Feature-Diagramm vs. Formeln Besser lesbar als Formel ( Management-kompatibel ) Weniger flexibel extra Formeln möglich Übersetzung Diagramm Formel automatisierbar 31

Feature-Diagramm vs. Formeln Besser lesbar als Formel ( Management-kompatibel ) Weniger flexibel extra Formeln möglich Übersetzung Diagramm Formel automatisierbar 32

Feature-Diagramm vs. Formeln Besser lesbar als Formel ( Management-kompatibel ) Weniger flexibel extra Formeln möglich Übersetzung Diagramm Formel automatisierbar 33

Beispiel FAME DBMS (Core) 34

Beispiel Berkeley DB (refaktorisiert) 35

Feature-Modell eines Speichermanagers

GUIDSL-Format Speichern des Feature-Diagramms als Grammatik Satz der Grammatik ist gültige Konfiguration Innere Features sind abstrakt, Blätter sind konkret Pr: [Feature1] [Feature2] Feature3 ::_Pr; Pr : Select+ :: _Pr ; Select : Feature1 Feature2 ; Pr: Feature1 Nesting Feature4::_Pr; Nesting: Feature2 Feature3::_Nesting; HowTo: 39 http://www.cs.utexas.edu/users/dsb/fopdocs/guidsl.html

Feature-Diagramm Varianten Viele verschiedene Varianten in der Literatur, z. B. Innere Features konkret oder abstrakt Mandatory/Optional in Oder/Alternative-Gruppen Requires/Excludes Pfeile Konvertierungen i.d.r. möglich requires 40

Konfiguration einer Variante FeatureIDE GUIDSL 41

FeatureIDE 42

Entwurf und Implementierung von Features Nach der Feature-Modellierung folgt der Entwurf und die Implementierung... Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. Feature-Auswahl Generator Fertiges Program 43

Zusammenfassung Produktlinien als Konzept zur systematischen Wiederverwendung Entwicklung teilt sich in Domain Engineering und Application Engineering Features repräsentieren Domänenkonzepte Produkte einer Produktlinie haben gemeinsame Features Feature-Modelle beschreiben Features und ihre Abhängigkeiten und werden zur Konfiguration benutzt 44

Ausblick Nächste Kapitel handeln von Methoden, Techniken und Werkzeugen zur Implementierung von Produktlinien 45

Literatur I S. Apel, D. Batory, C. Kästner, and G. Saake. Feature- Oriented Software Product Lines - Concepts and Implementation. Springer, 2013. Part 1: Software Product Lines K. Kang, S. Cohen, J. Hess, W. Novak, and A. Peterson. Feature-Oriented Domain Analysis (FODA) Feasibility Study. Technical Report CMU/SEI-90-TR-21, SEI,1990. [Frühe Ideen zur Domänenanalyse mit Feature-Modellen] K. Czarnecki and U. Eisenecker. Generative Programming: Methods, Tools, and Applications. Addison-Wesley, 2000. [Umfassende Beschreibung von Domain Engineering, Feature-Diagrammen und deren Normalisierung] 46

Literatur II D. Batory. Feature Models, Grammars, and Propositional Formulas, In Proc. of Software Product Line Conference (SPLC), 2005 Allgemeine Bücher zu Produktlinien: P. Clements, L. Northrop, Software Product Lines : Practices and Patterns, Addison-Wesley, 2002 K. Pohl, G. Böckle, F. van der Linden, Software Product Line Engineering: Foundations, Principles, and Techniques, Springer, 2005 47

Softwareproduktlinien - Laufzeitvariabilität Christian Kästner (Universität Marburg) Sven Apel (Universität Passau) Gunter Saake, Thomas Thüm (Universität Magdeburg) 1

Wie Variabilität implementieren? Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. 2 Feature-Auswahl Generator Fertiges Program

Agenda Graph-Beispiel Variabilität mit Laufzeitparametern Wiederholung: Modularität Design Patterns für Variabilität Grenzen herkömmlicher Techniken 3

4 Ein Beispiel

Beispiel: Graph-Bibliothek Durchgängiges Beispiel in Vorlesung (Chat-Client in der Übung) Bibliothek von Graph-Datenstrukturen und Algorithmen Gewichtete/ungewichtete Kanten Gerichtete/ungerichtete Kanten Gefärbte Knoten Algorithmen: kürzester Pfad, minimale Spannbäume, Transitive Hülle, 5

Graph-Feature-Modell 6

Beispiel: Graph-Implementierung class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = new Weight(); return e; class Node { int id = 0; Color color = new Color(); void print() { Color.setDisplayColor(color); System.out.print(id); Edge add(node n, Node m, Weight w) Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); class Edge { e.weight = w; return e; Node a, b; Color color = new Color(); void print() { Weight weight = new Weight(); for(int i = 0; i < ev.size(); i++) { Edge(Node _a, Node _b) { a = _a; b = _b; ((Edge)ev.get(i)).print(); void print() { Color.setDisplayColor(color); a.print(); b.print(); weight.print(); class Color { static void setdisplaycolor(color c) {... 7 class Weight { void print() {...

8 Laufzeitparameter

Parameter 9

Parameter i in grep 10

Globale Konfigurationsoptionen 11 class Conf { public static boolean Logging = false; public static boolean Windows = false; public static boolean Linux = true; class Main { public void foo() { if (Conf.Logging) log( running foo() ); if (Conf.Windows) callwindowsmethod(); else if (Conf.Linux) calllinuxmethod(); else throw RuntimeException();

Graph-Implementierung class Conf { public static boolean COLORED = true; public static boolean WEIGHTED = false; class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); if (Conf.WEIGHTED) e.weight = new Weight(); return e; Edge add(node n, Node m, Weight w) if (!Conf.WEIGHTED) throw RuntimeException(); Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); class Node { int id = 0; Color color = new Color(); void print() { if (Conf.COLORED) Color.setDisplayColor(color); System.out.print(id); class Edge { Node a, b; Color color = new Color(); Weight weight = new Weight(); Edge(Node _a, Node _b) { a = _a; b = _b; void print() { if (Conf. COLORED) Color.setDisplayColor(color); a.print(); b.print(); if (Conf.WEIGHTED) weight.print(); class Color { static void setdisplaycolor(color c) {... class Weight { void print() {... 12

Propagierte Parameter durch viele Aufrufe propagiert statt globaler Variable 13

Konfiguration Kommandozeilenparameter Config-Datei Dialog Quelltext 14

Diskussion Variabilität im gesamten Program verteilt Globale Variablen oder lange Parameterlisten Konfiguration geprüft? Änderungen zur Laufzeit möglich? Geschützt vor Aufruf deaktivierter Funktionalität? Kein Generator; immer alle Variabilität ausgeliefert Codegröße, Speicherverbrauch, Performance Ungenutzte Funktionalität als Risiko 15

Domain Eng. Parameterliste (Feature-Modell) Program mit Laufzeitparametern Application Eng. Parameterauswahl (Feature-Auswahl) Setzen der Startparameter Programmausführung mit gewünschtem Verhalten 16

17 Wiederholung: Modularität

Was ist Modularität? Modularität ist Kohäsion plus Kapselung Kapselung: Verstecken von Implementierungsdetails hinter einer Schnittstelle Kohäsion: Gruppieren verwandter Programmkonstrukte in einer adressierbaren Einheit (z.b. Paket, Klasse, ) Kohäsive und schwach gekoppelte Module können isoliert verstanden werden Reduziert die Komplexität des Softwareentwicklungsprozesses 18

Kapselung public class ArrayList<E> { public void add(int index, E element) { if (index > size index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); ensurecapacity(size+1); System.arraycopy(elementData, index, elementdata, index + 1, size - index); elementdata[index] = element; size++; public int indexof(object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementdata[i]==null) return i; else { for (int i = 0; i < size; i++) if (o.equals(elementdata[i])) return i; return -1;. 19 public interface List<E> { void add(int index, E element); int indexof(object o);. Implementierungsdetails werden versteckt Schnittstelle beschreibt Verhalten Implementierung wird austauschbar

Kohäsion/Kopplung Beispiel Gruppierung von Methoden/Aufgaben Viele Aufrufe über Grenzen der Gruppe Gruppe implementiert verschiedene Belange 20

Warum Modularität? Software leicht verständlich (divide and conquer) Versteckt Komplexität von Teilstücken hinter Schnittstellen (information hiding) Einfacher zu warten, da Änderungen lokal erfolgen können (maintainability) Teile der Software können wiederverwendet werden (reusability) Module können auch in neuem Kontext in anderen Projekte neu zusammengestellt werden (variability) 21

Zerlegung und Wiederverwendung 22

Probleme? Verstreuter Code class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); if (Conf.WEIGHTED) e.weight = new Weight(); return e; Edge add(node n, Node m, Weight w) if (!Conf.WEIGHTED) throw RuntimeException(); Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); Code Scattering class Node { int id = 0; Color color = new Color(); void print() { if (Conf.COLORED) Color.setDisplayColor(color); System.out.print(id); class Edge { Node a, b; Color color = new Color(); Weight weight; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { if (Conf. COLORED) Color.setDisplayColor(color); a.print(); b.print(); if (!Conf.WEIGHTED) weight.print(); class Color { static void setdisplaycolor(color c) {... class Weight { void print() {... 23

Probleme? Vermischter Code class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); if (Conf.WEIGHTED) e.weight = new Weight(); return e; Edge add(node n, Node m, Weight w) if (!Conf.WEIGHTED) throw RuntimeException(); Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); Code Tangling class Node { int id = 0; Color color = new Color(); void print() { if (Conf.COLORED) Color.setDisplayColor(color); System.out.print(id); class Edge { Node a, b; Color color = new Color(); Weight weight; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { if (Conf. COLORED) Color.setDisplayColor(color); a.print(); b.print(); if (!Conf.WEIGHTED) weight.print(); class Color { static void setdisplaycolor(color c) {... class Weight { void print() {... 24

Probleme? Replizierter Code class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); if (Conf.WEIGHTED) e.weight = new Weight(); return e; Edge add(node n, Node m, Weight w) if (!Conf.WEIGHTED) throw RuntimeException(); Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); Code Replication class Edge { class Node { int id = 0; Color color = new Color(); void print() { if (Conf.COLORED) Color.setDisplayColor(color); System.out.print(id); Node a, b; Color color = new Color(); Weight weight; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { if (Conf. COLORED) Color.setDisplayColor(color); a.print(); b.print(); if (!Conf.WEIGHTED) weight.print(); class Color { static void setdisplaycolor(color c) {... class Weight { void print() {... 25

26 Design Patterns für Variabilität

Design Patterns Muster für den Entwurf von Lösungen für wiederkehrende Probleme Viele Design Patterns für Variabilität, Entkoppelung und Erweiterbarkeit Hier Auswahl: Observer Template Method Strategy Decorator 27

Observer Pattern Observers VIEW Subject A = 50% B = 30% C = 20% [Quelle: Meyer/Bay] 28

Observer Pattern Define[s] a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. [GoF, p 293] Observer 1) Bekundet Interesse Subject 2) Merke Interessenten 3) Informiert über Event Interfaces fügen zusätzliche Flexibilität hinzu In Implementierung Klasse für Observer Klasse für Subject Liste in Subject für Observer Subject.addToObservers(Observer) (wird vom Observer aufgerufen) Observer.notify() (wird von Subject aufgerufen) 29 29

Template Method Pattern public abstract class BubbleSorter{ protected int length = 0; protected void sort() { if (length <= 1) return; for (int nexttolast= length-2; nexttolast>= 0; nexttolast--) for (int index = 0; index <= nexttolast; index++) if (outoforder(index)) swap(index); protected abstract void swap(int index); protected abstract boolean outoforder(int index); 30

IntBubbleSorter public class IntBubbleSorter extends BubbleSorter{ private int[] array = null; public void sort(int[] thearray) { array = thearray; length = array.length; super.sort(); protected void swap(int index) { int temp = array[index]; array[index] = array[index+ 1]; array[index+1] = temp; protected boolean outoforder(int index) { return (array[index] > array[index+ 1]); 31

Strategy Pattern 32

Strategy Pattern: Beispiel 33

34 Problem: Unflexible Erweiterungsmechanismen

Unflexible Erweiterungsmechanismen Subklassen für Erweiterungen: modular, aber unflexibel Kein mix & match Stack Stack SecureStack UndoStack SecureStack SynchronizedStack SynchronizedStack UndoStack 35 z. B. White-Box-Framework

Lösung I Kombinierte Klassenhierarchien Kombinatorische Explosion der Varianten Massive Code-Replikation Stack SynchronizedStack UndoStack SecureStack SynchronizedUndoStack UndoSecureStack Mehrfachvererbung Kombinatorische Explosion SynchronizedUndoSecureStac Aufgrund diverser Probleme (u. a. Diamant-Problem) in nur wenigen Sprachen verfügbar 36

Diamant-Problem Stack -values +push() +pop() +size() Was passiert? new LockedUndoStack().pop() UndoStack -log +push() +pop() +undo() LockedStack +push() +pop() +size() +lock() +unlock() Multiple inheritance is good, but there is no good way to do it. A. SYNDER LockedUndoStack 37

Delegation statt Vererbung class LockedStack implements IStack { final IStack _delegate; public LockedStack(IStack delegate) { this._delegate = delegate; private void lock() { /*... /* private void unlock() { /*... /* public void push(object o) { lock(); _delegate.push(o); unlock(); public Object pop() { lock(); Object result = _delegate.pop(); unlock(); return result; public int size() { return _delegate.size(); class UndoStack implements IStack { final IStack _delegate; public UndoStack(IStack delegate) { this._delegate = delegate; public void undo() { /*... /* public void push(object o) { remember(); _delegate.push(o); public Object pop() { remember(); return _delegate.pop(); public int size() { return _delegate.size(); Main: IStack stack = new UndoStack( new LockedStack(new Stack())); 38

Decorator Pattern «interface» IStack +push() +pop() +size() 1 1 Stack StackDecorator -values -delegate +push() +pop() +size() +push() +pop() +size() LockedStack UndoStack SecureStack -log -keyphrase 39 +push() +pop() +size() +lock() +unlock() +push() +pop() +undo() +push() +pop() +encrypt() +decrypt()

Beispiel: Decorator in java.io java.io enthält verschiedene Funktionen zur Ein- und Ausgabe: Programme operieren auf Stream-Objekten... Unabhängig von der Datenquelle/-ziel und der Art der Daten 40

Delegation statt Vererbung Diskussion Dynamische Kombination möglich Erweiterungen müssen alle unabhängig sein Kann keine Methoden hinzufügen, nur bestehende erweitern Kein spätes Binden (keine virtuellen Methoden) Viele Indirektionen in der Ausführung (Performance) Mehrere Objektinstanzen bilden ein Objekt (Objektschizophrenie) 41

Flexible Erweiterungsmechanismen???? 42

Ausblick Konfiguration mit Generator zur Übersetzungszeit Flexiblere Erweiterungsmechanismen Modularisierung von Features 43

Literatur Gamma, Erich; Richard Helm, Ralph Johnson, and John Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. ISBN 0-201- 63361-2. [Standardwerk Design Patterns] Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall, 1997 Chapters 3, 4 [Zu Modularität] 44

Softwareproduktlinien - Versionsverwaltungs- und Buildsysteme Christian Kästner (Carnegie Mellon University) Sven Apel (Universität Passau) Gunter Saake, Thomas Thüm (Universität Magdeburg) 1

Wie Variabilität implementieren? Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. 2 Feature-Auswahl Generator Fertiges Program

Wiederholung: Variabilität zur Laufzeit Parameter Globale Konfiguration vs. propagierte Parameter Design Patterns Observer (Observer und Subject) Template Method (Vererbung) Strategy Pattern (Context + Interface für alternative Algorithmen) Decorator Pattern (Delegation + Interface) 3

Variabilität zur Übersetzungszeit Ziel: Nur benötigter Quelltext wird mit übersetzt Kleine, optimierte Varianten Quelltext wird passend ausgewählt und zusammengebaut Wie Optionen oder Alternativen implementieren? Hier einfache Mittel für wenig Varianten 4

5 Versionsverwaltungssysteme

Versionsverwaltung Teil des Konfigurationsmanagments Versionierung von Quelltextdateien Gemeinsame Entwicklung Archiv alter Quelltextversionen Zeitstempel und Benutzerkennung Änderungen als Delta Prozess: Checkout Change Commit Update Change Commit - Beispielsysteme: CVS, SVN, Visual SourceSafe, Perforce, SCCS, Git, Mercurial 6

Branching & Merging 7

Release-Planung 8

Varianten Graph-Bibliothek Variante 3 ohne Gewichte und ohne Farben Schnellere Suche Variante 2 ohne Gewichte Basis-Variante (mit Farben und Gewichten) 9 NullPointer- Exception abgefangen

Code und Nicht-Code Dateien Java Code Dokumentation Modelle Build-Scripte: Ant/Makefile Lizenzen Grammatiken Kompilierte Dateien HTML, JavaScript, CSS Bei Binärdateien ist Konfliktbehandlung und Mischen schwieriger 10

Varianten vs. Revisionen 11 [Staples&Hill, APSEC 04]

Varianten vs. Revisionen Revisionen V1.0 V1.1 V2.0 V3.0 Varianten Sensor-DB (Auto) Sensor-DB (Habitat Monitoring) Sensor-DB (Erdbeben) SmartCard-DB GPS-DB X X X X X X X X X X X X X X 12

Produktlinien mit Versionsverwaltung Entwicklung von Varianten in Branches Mergen von Änderungen zwischen Branches Domain Eng. Mapping von Variante zu Branch Varianten-Liste Sensor-DB (Auto) Sensor-DB (Habitat Monitoring) Sensor-DB (Erdbeben) SmartCard-DB GPS-DB Versionsverwaltung mit Branches Application Eng. Sensor-DB (Auto) Sensor-DB (Habitat Monitoring) Sensor-DB (Erdbeben) SmartCard-DB GPS-DB 13 Varianten-Auswahl Variante als Eingabe Checkout des passenden Branches Fertiges Program

Produktlinien mit Versionsverwaltung Diskussion Vorteile Etablierte, stabile Systeme Bekannter Prozess Gute Werkzeugintegration Nachteile Vermischen von Revisionen und Varianten Entwicklung von Varianten, nicht Features: flexible Kombination von Features nicht direkt möglich Keine strukturierte Wiederverwendung (Copy & Edit) Hoher Aufwand für Wartung (Merging) 14

15 Build-Systeme

Build-Systeme Automatisierung des Build-Prozesses Kopiert Dateien, ruft Compiler auf, startet weitere Tools Mehrere Schritte mit Abhängigkeiten/Bedingungen Werkzeuge: make, ant, maven, 16

Produktlinien mit Build-Systemen Pro Variante eine Konfigurationsdatei/ein Build-Skript Dateien beim Übersetzen einbeziehen/ausschließen Dateien mit produktspezifischen Varianten überschreiben 17

Beispiel: Graph-Bibliothek Basis- Implementierung build.xml src Graph.java class Edge { Node a, b; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { a.print(); b.print(); Edge.java Variante mit Gewichten 18 build.xml src Edge.java class Edge { Node a, b; Weight weight; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { a.print(); b.print(); weight.print();

Alternatives Beispiel: Graph-Bibliothek Basis- Implementierung build.xml src Graph.java class Edge { Node a, b; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { a.print(); b.print(); Edge.java Variante mit Gewichten 19 build.xml src WEdge.java class WEdge extends Edge { Weight weight; void print() { super.print(); weight.print(); und alle new-aufrufe anpassen; ggf. Factory Pattern verwenden

Produktlinien mit Build-Systemen Basis-Implementierung Domain Eng. Feature-Modell Application Eng. Sensor-DB (Auto) Sensor-DB (Habitat Monitoring) Sensor-DB (Erdbeben) SmartCard-DB GPS-DB Build-Skript pro Variante + spezifische Dateien Standard Build (make, ant, ) Fertiges Program 20

Produktlinien mit Build-Systemen Bewertung Relativ einfacher Mechanismus Hohe Flexibilität beliebige Änderungen für Varianten Wenig Vorplanung nötig Entwicklung für jede Variante getrennt, ggf. hoher Aufwand im Application Engineering Änderungen nur auf Dateiebene (überschreiben ganzer Dateien) Änderungen an der Basisimplementierung schwierig 21

Ausblick Weitere Methoden zur Implementierung von Variabilität zur Übersetzungszeit Aber: Features statt Varianten entwickeln 22

Literatur S. Apel, D. Batory, C. Kästner, and G. Saake. Feature- Oriented Software Product Lines - Concepts and Implementation. Springer, 2013. Section 5.1/5.2: Version Control Systems, Build Systems M. Staples, D. Hill. Experiences adopting software product line development without a product line architecture. Proceedings APSEC, pp. 176 183, 2004 [Industrielle Erfahrung zu Versionsverwaltung und Build-Systemen für die Produktlinienentwicklung] T. Dhaliwal, F. Khomh, Y. Zou, A. Hassan. Recovering commit dependencies for selective code integration in software product lines. Proceedings ICSM, 202 211, 2012 [Zuordnung von Commits zu Features; Abhängigkeitsanalyse] 23

Softwareproduktlinien Teil 5: Präprozessoren Christian Kästner (CMU) Sven Apel (Universität Passau) Gunter Saake, Thomas Thüm (Universität Magdeburg)

Wie Variabilität implementieren? Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. 2 Feature-Auswahl Generator Fertiges Program

Variabilität zur Übersetzungsszeit Ziel: Nur benötigter Quelltext wird kompiliert Aber Features flexibel auswählbar 3

Was fehlte? if nicht erst zur Laufzeit auswerten Ganze Methoden und Klassen auf Wunsch entfernen Alternativen zulassen wirklich entfernen entfernen entfernen 4 class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); if (Conf.WEIGHTED) e.weight = new Weight(); return e; Edge add(node n, Node m, Weight w) if (!Conf.WEIGHTED) throw RuntimeException(); Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); class Conf { public static boolean COLORED = true; public static boolean WEIGHTED = false; class Node { int id = 0; Color color = new Color(); void print() { if (Conf.COLORED) Color.setDisplayColor(color); System.out.print(id); class Edge { Node a, b; Color color = new Color(); Weight weight; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { if (Conf. COLORED) Color.setDisplayColor(color); a.print(); b.print(); if (!Conf.WEIGHTED) weight.print(); class Color { static void setdisplaycolor(color c) {... class Weight { void print() {...

Was fehlte? Feature-basierte Planung und Variantenerzeugung Fein-granulare Variabilität Features explizit im Quelltext machen 5

6 Präprozessoren

Präprozessoren Transformieren Quelltext vor Aufruf des Compilers Von einfachen #include-befehlen und bedingter Übersetzung zu komplexen Makrosprachen und Regeln In vielen Programmiersprachen üblich C, C++, Fortran, Erlang mit eigenem Präprozessor C#, Visual Basic, D, PL/SQL, Adobe Flex 7

#ifdef Beispiel aus Berkeley DB 8 static int rep_queue_filedone(dbenv, rep, rfp) DB_ENV *dbenv; REP *rep; rep_fileinfo_args *rfp; { #ifndef HAVE_QUEUE COMPQUIET(rep, NULL); COMPQUIET(rfp, NULL); return ( db_no_queue_am(dbenv)); #else db_pgno_t first, last; u_int32_t flags; int empty, ret, t_ret; #ifdef DIAGNOSTIC DB_MSGBUF mb; #endif // over 100 lines of additional code #endif

Präprozessor in Java? Nicht nativ vorhanden Bedingte Kompilierung in manchen Fällen möglich; nur auf Statement-Ebene, nicht für Klassen oder Methoden class Example { public static final boolean DEBUG = false; void main() { System.out.println( immer ); if (DEBUG) System.out.println( debug info ); Externe Tools, z.b. CPP, Antenna, Munge, XVCL, Gears, pure::variants 9

Munge Simpler Präprozessor für Java-Code Ursprünglich für Swing in Java 1.2 class Example { void main() { System.out.println( immer ); /*if[debug]*/ System.out.println( debug info ); /*end[debug]*/ java Munge DDEBUG DFEATURE2 Datei1.java Datei2.java... Zielverzeichnis 10 Feature-Auswahl aus Feature-Modell http://weblogs.java.net/blog/tball/archive/2006/09/munge_swings_se.html

Wiederholung: Graph-Beispiel class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = new Weight(); return e; Edge add(node n, Node m, Weight w) Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); class Color { static void setdisplaycolor(color c) {... class Node { int id = 0; Color color = new Color(); void print() { Color.setDisplayColor(color); System.out.print(id); class Edge { Node a, b; Color color = new Color(); Weight weight; = new Weight(); Edge(Node _a, Node _b) { a = _a; b = _b; void print() { Color.setDisplayColor(color); a.print(); b.print(); weight.print(); class Weight { void print() {... 11

Graph-Beispiel mit Munge class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); /*if[weight]*/ e.weight = new Weight(); /*end[weight]*/ return e; /*if[weight]*/ Edge add(node n, Node m, Weight w) Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; /*end[weight]*/ void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); /*if[weight]*/ class Weight { void print() {... /*end[weight]*/ 12 class Edge { Node a, b; /*if[color]*/ Color color = new Color(); /*end[color]*/ /*if[weight]*/ Weight weight; /*end[weight]*/ Edge(Node _a, Node _b) { a = _a; b = _b; void print() { /*if[color]*/ Color.setDisplayColor(color); /*end[color]*/ a.print(); b.print(); /*if[weight]*/ weight.print(); /*end[weight]*/ /*if[color]*/ class Color { static void setdisplaycolor(color c) {... /*end[color]*/ class Node { int id = 0; /*if[color]*/

Produktlinien mit Präprozessoren Domain Eng. Feature-Modell Programm mit Präprozessor-Anweisungen Application Eng. Feature-Auswahl Feature-Auswahl als Eingabe Präprozessor Fertiges Program 13

14 Weitere Präprozessoren

XVCL XML-basierter Präprozessor Basiert auf Frame-Hierarchie <x-frame name="notepad"> import java.awt.*; class Notepad extends JPanel { Notepad() { super(); public static void main(string[] args) { JFrame frame = new JFrame(); frame.settitle("<value-of expr="?@title?"/>"); frame.setbackground( Color.<value-of expr="?@bgcolor?"/>); frame.show(); <adapt x-frame="editor.xvcl"/> <adapt x-frame="menubar.xvcl"/> <adapt x-frame="toolbar.xvcl"/> </x-frame> 15 <x-frame name="toolbar"> <set-multivar="toolbarbtns" value="new,open,save"/> private Component createtoolbar() { JToolBar toolbar = new JToolBar(); JButton button; <while using-items-in="toolbarbtns"> <select option="toolbarbtns"> <option value="-"> toolbar.add(box.createhorizontalstrut(5)); </option> <otherwise> button = new JButton(new ImageIcon( "<value-of expr="?@gif@toolbarbtns?"/> ")); toolbar.add(button); </otherwise> </select> </while> toolbar.add(box.createhorizontalglue()); return toolbar; </x-frame>

XVCL Basiert auf Frame-Hierarchie Notepad Editor Menubar Toolbar NewFile OpenFile 16 FileLoader

Antenna Sammlung von Ant-Tasks für Java ME Enthält Präprozessor: #ifdef wie in cpp Benutzt in vielen Java-ME Projekten 17 http://antenna.sourceforge.net/

Tag and Prune 18 Patrick Heymans, Quentin Boucher, Andreas Classen, Arnaud Bourdoux, Laurent Demonceau: A code tagging approach to software product line development - An application to satellite communication libraries. STTT 14(5): 553-566 (2012)

19 Diskussion

Vorteile von Präprozessoren In vielen Sprachen bereits enthalten / simple Tools Den meisten Entwicklern bekannt Sehr einfaches Programmierkonzept: markieren und entfernen Sehr flexibel, ausdrucksstark, beliebig fein-granular Nachträgliche Einführung von Variabilität in bestehendes Projekt einfach 20

Problem: Unlesbarer Quelltext Vermischung von zwei Sprachen (C und #ifdefs, oder Java und Munge, ) Kontrollfluss schwer nachvollziehbar Lange Annotationen schwer zu finden Zusätzliche Zeilenumbrüche zerstören Layout Features lieber modularisieren? 21 class Stack { void push(object o #ifdef SYNC, Transaction txn #endif ) { if (o==null #ifdef SYNC txn==null #endif ) return; #ifdef SYNC Lock l=txn.lock(o); #endif elementdata[size++] = o; #ifdef SYNC l.unlock(); #endif firestackchanged();

Präprozessor in Femto Os 22

Probleme von Präprozessoren Komplexität durch beliebige Schachtelung Fehleranfälligkeit durch Komplexität und unkontrollierten undisziplinierten Einsatz Beispiele: Variabler Rückgabetyp /*if[weight]*/w/*end[weight]*/edge add(node n, Node m /*if[weight]*/, int w/*end[weight]*/) { return new /*if[weight]*/w/*end[weight]*/edge (n, m /*if[weight]*/, w/*end[weight]*/ ); Komma bei mehreren Parametern Edge set(/*if[weight]*/int w/*if[color]*/, /*end[color]*/ /*end[weight]*/ /*if[color]*/int c/*end[color]*/ ) { 23

Problem: Fehleranfällig Syntaxfehler Typfehler static int _rep_queue_filedone(...) DB_ENV *dbenv; REP *rep; rep_fileinfo_args *rfp; { #ifndef HAVE_QUEUE COMPQUIET(rep, NULL); COMPQUIET(rfp, NULL); return ( db_no_queue_am(dbenv)); #else db_pgno_t first, last; u_int32_t flags; int empty, ret, t_ret; #ifdef DIAGNOSTIC DB_MSGBUF mb; #endif //over 100 lines of additional code #endif 24 #ifdef TABLES class Table { void insert(object data, Txn txn) { storage.set(data, txn.getlock()); #endif class Storage { #ifdef WRITE boolean set( ) {... #endif

Probleme von Präprozessoren II Feature-Code ist komplett verstreut Feature-Traceability-Problem Wie findet man einen Fehler im Feature Weight? Verhindert/erschwert Tool Support Erfahrungen aus C/C++ (Refactoring, Analyse, ) Munge und andere: Definition in Kommentaren 25

Eine Frage der Größe Beispiel: Zeitmanagement von Sessions im Apache Tomcat Server als Bestandteil der Session-Verwaltung 26

27 Das Feature-Tracability-Problem

Problem: Verteilte Implementierung Feature verschwinden in der Implementierung Was gehört alles zu einem Feature? Bei Wartungsaufgaben muss der ganze Quelltext durchsucht werden Schwierige Arbeitsteilung Für unterschiedliche Features kann es unterschiedliche Experten geben; alle müssen am gleichen Code-Fragment arbeiten Geringere Produktivität, schwierige Evolution Beim Hinzufügen neuer Funktionalitäten muss sich der Entwickler um diverse andere Belange kümmern, die erstmal nur ablenken (Lesbarkeit, Erfassbarkeit) 28

Features im Graph-Beispiel class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = new Weight(); return e; Edge add(node n, Node m, Weight w) Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); class Node { int id = 0; Color color = new Color(); void print() { Color.setDisplayColor(color); System.out.print(id); class Edge { Node a, b; Color color = new Color(); Weight weight; = new Weight(); Edge(Node _a, Node _b) { a = _a; b = _b; void print() { Color.setDisplayColor(color); a.print(); b.print(); weight.print(); class Color { static void setdisplaycolor(color c) {... 29 class Weight { void print() {...

Konsequenzen class BusinessClass //... Datenfelder //... Logging Stream //... Cache Status public void importantoperation( Data data, User currentuser,...){ // prüfe Autorisierung // Objekt sperren für Synchronisation // Aktualität des Puffers prüfen // Start der Operation loggen // eigentliche Operation ausführen // Ende der Operation loggen // Sperre auf Objekt freigeben public void alsoimportantoperation( OtherData data, User currentuser,...){ // prüfe Autorisierung // Objekt sperren für Synchronisation // Aktualität des Puffers prüfen // Start der Operation loggen // eigentliche Operation ausführen // Ende der Operation loggen // Sperre auf Objekt freigeben Welcher Code gehört zur Authentifizierung? Das Sperrverfahren soll geändert werden: welcher Code muss angepasst werden? Nutzer konnte ohne Anmeldung Daten löschen: wo Fehler suchen? 30

Erneut: Eine Frage der Größe Beispiel: Zeitmanagement von von Sessions im im Apache Tomcat Server als Bestandteil der Session-Verwaltung 31

Feature Traceability Man möchte den Zusammenhang zwischen Code und Feature erhalten Am besten pro Feature ein Modul Umwege und Notlösungen unausweichlich, wenn Modularisierung nicht möglich Kommentare oder Annotationen im Quelltext (z. B. jeglicher Authentifizierungscode wird mit //auth markiert) Namenskonventionen (z. B. alle Authentifizierungs-methoden fangen mit auth_ an) Zusätzliche Werkzeuge z. B. IDE-Unterstützung Präprozessoren bieten bereits Annotationen für Features 32

CIDE FeatureCommander http://fosd.net/cide http://fosd.net/fc 33

Ausblick Modulare Form der Feature-Implementierung Querschneidende Belange 34

Softwareproduktlinien - Komponenten und Frameworks Christian Kästner (CMU) Sven Apel (Universität Passau) Gunter Saake, Thomas Thüm (Universität Magdeburg) 1

Wiederholung: Konfigurationsmanagement und Präprozessoren Variabilität zur Übersetzungszeit Versionsverwaltungssysteme Nur für wenig Varianten geeignet, dafür etabliert Flexible Kombination von Features nicht möglich Build-Systeme Einfacher Mechanismus mit hoher Flexibilität Entwicklung von Varianten getrennt (keine einzelnen Features) Änderungen auf Dateiebene (eingeschränkte Wiederverwendbarkeit) Präprozessoren Einfaches Muster: markieren und entfernen Standard-Tools, hohe Flexibilität, feine Granularität, Feature-basiert Fehleranfällig, schwer lesbar, scattering/tangling, Wie können Features modular implementiert werden? 2

Wie Variabilität modular implementieren? Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. Feature-Auswahl Generator Fertiges Program 3

4 Komponenten

Komponente Abgeschlossene modulare Implementierungseinheit mit Schnittstelle (black box); bietet einen Dienst an Wird zusammen mit anderen Komponenten auch von anderen Herstellern zusammengesetzt zu Softwaresystemen (Komposition) Einzeln vermarktbar und lauffähig Kontext (z. B. JavaEE, CORBA, COM+/DCOM, OSGi) und Abhängigkeiten (imports, exports) explizit spezifiziert Klein genug für Erzeugung und Wartung in einem Stück, groß genug um sinnvolle Funktion bieten zu können 5

Komponenten vs. Objekte/Klassen Ähnliche Konzepte: Kapselung, Interfaces, Geheimnisprinzip Objekte strukturieren ein Problem Komponenten bieten wiederverwendbare Teilfunktionalität Objekte sind üblicherweise kleiner als Komponenten: Komponenten skalieren Objektorientierung Objekte haben häufig viele Abhängigkeiten zu anderen Objekten; Komponenten haben wenig Abhängigkeiten Interfaces von Objekten sind häufig implementierungsnah; Komponenten abstrahieren mehr 6

Vision: Märkte für Komponenten Komponenten können gekauft und in eigene Produkte integriert werden Best of Breed: Entwickler kann für jedes Teilsystem den besten/billigsten Anbieter auswählen Anbieter können sich auf Kernkompetenz beschränken und diese als Komponente(n) anbieten 7

Komponenten eines Webshops (UML-Notation) Bestellen Großhändler Kunde anlegen Adresse ändern Kundenverwaltung Rechnung drucken Reportgenerator Einkäufe Katalog verwalten Webshop Rechnung schreiben Finanzbuchhaltung Entnehmen Einlagern Lagerhaltung Szenario: Kunde anlegen Einkauf Rechnung schreiben Rechnung drucken 8

Produktlinien aus Komponenten Features werden in verschiedenen Komponenten implementiert z. B. die Komponenten Transaktionsverwaltung, Log/Recovery, Pufferverwaltung, Optimierer Komponenten können ggf. Laufzeitvariabilität enthalten Durch Feature-Auswahl werden Komponenten ausgewählt (mapping) Der Entwickler muss Komponenten verbinden (glue code) 9

Produktlinien aus Komponenten Feature-Modell Mapping von Features zu Komponenten Komponentensammlung Component10 Component6 Component2 Component12 Component5 Component1 Component9 Feature-Auswahl als Eingabe Component3 Component7 Component4 Component8 Component11 Component2 Entwickler baut fertiges Programm aus Komponenten Component6 Component9 Component8 Feature-Auswahl Komponentenauswahl Menge von Komponenten Fertiges Program 11

Wie Komponenten bestimmen? Markt für beliebige Komponenten funktioniert nicht Zu kleine Komponenten hoher Aufwand Zu große Komponenten kaum wiederverwendbar Produktlinien liefern nötige Domänenanalyse Welche Teilfunktionalität wird in welcher Granularität wiederverwendet Systematische Wiederverwendung 12 (Tangram)

Bewertung: Produktlinien aus Komponenten In der Industrie üblich (Beispiel: Heimelektronik mit Koala-Komponenten von Phillips) Produktlinien zum Domain Engineering, zur Organisation der Entwicklung, Systematische (geplante) Wiederverwendung von Komponenten Keine vollständige Automatisierung, hoher Entwicklungsaufwand (glue code) im Application Engineering Keine freie Feature-Auswahl 14

Diskussion: Modularität Komponenten verstecken interne Implementierung Idealerweise kleine Interfaces Feature-Kohäsion aber Grobe Granularität Seitenwechselstrategien, Suchalgorithmen, Locking im B-Baum, oder VARCHAR als Komponente? Farben oder gewichtete Kanten im Graph als Komponenten? Funktionalität ggf. schwer als Komponente zu kapseln Transaktionsverwaltungskomponente? 15

Services Ähnlich zu Komponenten: kapseln Teilfunktionalität (Dienste) i.d.r. verteiltes Szenario Bus-Kommunikation, Web Services, SOAP, REST Produktlinien durch Verbinden von Services, i.d.r. mit Orchestrierung (Workflow-Sprachen wie BPEL) Viele Werkzeuge verfügbar (teils managementgerecht ) 16

17 Frameworks

Frameworks Menge abstrakter und konkreter Klassen Abstrakte Struktur, die für einen bestimmten Zweck angepasst/erweitert werden kann vgl. Template Method Pattern und Strategy Pattern Wiederverwendbare Lösung für eine Problemfamilie in einer Domäne Punkte an denen Erweiterungen vorgesehen sind: hot spots (auch variation points, extension points) Umkehrung der Kontrolle, das Framework bestimmt die Ausführungsreihenfolge Hollywood-Prinzip: Don t call us, we ll call you. 18

Plug-ins Erweiterung eines Frameworks Spezielle Funktionen bei Bedarf hinzufügen Üblicherweise getrennt kompiliert; third-party Beispiele: Email-Programme, Grafikprogramme, Media- Player, Web browser 19

Web Portal Webapplikation- Frameworks wie Struts, die grundlegende Konzepte vorgeben und vorimplementieren Entwickler konzentrieren sich auf Anwendungslogik statt Navigation zwischen Webseiten <?php class WebPage { function getcssfiles(); function getmoduletitle(); function hasaccess(user u); function printpage();?> <?php class ConfigPage extends WebPage { function getcssfiles() { function getmoduletitle() { return Configuration ; function hasaccess(user u) { return user.isadmin(); function printpage() { print <form><div> ;?> 20

Eclipse Eclipse als Framework für IDEs Nur sprachspezifische Erweiterungen (Syntax Highlighting, Compiler) müssen implementiert werden Der gemeinsame Teil (Editoren, Menüs, Projekte, Verzeichnisbaum, Copy & Paste & Undo Operationen, CVS, uvm.) ist durch das Framework vorgegeben Framework aus vielen kleineren Frameworks 21

Eclipse JDT WTP SAPinst Workbench Build Debug Edit JUnit Refactor Launch Platform Ant IDE Cheat Sheets Search Debug Team Help Update Views Resources Console Editors Forms Text Editors Compare J2EE Web Control Items Component Messages Resourcepool Dialogs Weitere Erweiterungen Table Script Meta-Dialogs Prerequisite C. Rich Client Platform Workbench Help JFace Core Runtime OSGi SWT 22

Weitere Framework-Beispiele Frameworks für graphische Benutzeroberflächen, z.b. MacApp, Swing, SWT, MFC Multimedia-Frameworks, z.b. DirectX Instant Messenger-Frameworks, z.b. Miranda, Trillian,... Compiler-Frameworks, z.b. Polyglot, abc, JastAddJ 23

Framework-Implementierung: Mini-Beispiel Familie von Dialogen, bestehend aus Textfeld und Button 90% des Quelltexts sind gleich Main Methode Initialisierung von Fenster, Textfeld und Button Layout Schließen des Fensters 24

Taschenrechner public class Calc extends JFrame { private JTextField textfield; public static void main(string[] args) { new Calc().setVisible(true); public Calc() { init(); protected void init() { JPanel contentpane = new JPanel(new BorderLayout()); contentpane.setborder(new BevelBorder(BevelBorder.LOWERED)); JButton button = new JButton(); button.settext("calculate"); contentpane.add(button, BorderLayout.EAST); textfield = new JTextField(""); textfield.settext("10 / 2 + 6"); textfield.setpreferredsize(new Dimension(200, 20)); contentpane.add(textfield, BorderLayout.WEST); button.addactionlistener(/* code zum berechnen */); this.setcontentpane(contentpane); this.pack(); this.setlocation(100, 100); this.settitle("my Great Calculator"); // code zum schliessen des fensters 25

White-Box Frameworks Erweiterung durch Überschreiben und Hinzufügen von Methoden (vgl. Template Method Pattern) Interna des Framework müssen verstanden werden schwierig zu lernen Flexible Erweiterung Viele Subklassen nötig u.u. unübersichtlich Status direkt verfügbar durch Superklasse Keine Plug-ins, nicht getrennt kompilierbar 26

Taschenrechner als Whitebox-Framework public abstract class Application extends JFrame { protected abstract String getapplicationtitle(); //Abstrakte Methoden protected abstract String getbuttontext(); protected String getinititaltext() {return ""; protected void buttonclicked() { private JTextField textfield; public Application() { init(); protected void init() { JPanel contentpane = new JPanel(new BorderLayout()); contentpane.setborder(new BevelBorder(BevelBorder.LOWERED)); JButton button = new JButton(); button.settext(getbuttontext()); contentpane.add(button, BorderLayout.EAST); textfield = new JTextField(""); textfield.settext(getinititaltext()); textfield.setpreferredsize(new Dimension(200, 20)); contentpane.add(textfield, BorderLayout.WEST); button.addactionlistener(/* buttonclicked(); */); this.setcontentpane(contentpane); this.pack(); this.setlocation(100, 100); this.settitle(getapplicationtitle()); // code zum schliessen des fensters protected String getinput() { return textfield.gettext(); 27

Taschenrechner als Whitebox-Framework public abstract class Application extends JFrame { protected abstract String getapplicationtitle(); //Abstrakte Methoden protected abstract String getbuttontext(); protected String getinititaltext() {return ""; protected void buttonclicked() { private JTextField textfield; public Application() { init(); public class Calculator extends Application { protected void init() { protected String getbuttontext() { return "calculate"; JPanel contentpane = new JPanel(new BorderLayout()); protected String getinititaltext() { return "(10 3) * 6"; contentpane.setborder(new BevelBorder(BevelBorder.LOWERED)); protected void buttonclicked() { JButton button = new JButton(); JOptionPane.showMessageDialog(this, "The result of "+getinput()+ button.settext(getbuttontext()); " is "+calculate(getinput())); contentpane.add(button, BorderLayout.EAST); protected String getapplicationtitle() { return "My Great Calculator"; textfield = new JTextField(""); public static void main(string[] args) { textfield.settext(getinititaltext()); new Calculator().setVisible(true); textfield.setpreferredsize(new Dimension(200, 20)); contentpane.add(textfield, BorderLayout.WEST); button.addactionlistener(/* buttonclicked(); */); public this.setcontentpane(contentpane); class Ping extends Application { this.pack(); protected String getbuttontext() { return "ping"; this.setlocation(100, protected String 100); getinititaltext() { return "127.0.0.1"; this.settitle(getapplicationtitle()); protected void buttonclicked() { /* */ // code zum protected schliessen String des getapplicationtitle() fensters { return "Ping"; public static void main(string[] args) { protected String getinput() new { return Ping().setVisible(true); textfield.gettext(); 28

Black-Box Frameworks Einbinden des anwendungsspezifischen Verhalten durch Komponenten mit speziellem Interface (plug-in) vgl. Strategy Pattern, Observer Pattern Nur das Interface muss verstanden werden einfacher zu lernen, aber aufwendiger zu entwerfen Flexibilität durch bereitgestellte Hot Spots festgelegt, häufig Design Patterns Status nur bekannt wenn durch Interface verfügbar Insgesamt besser wiederverwendbar (?) 29

Taschenrechner public class Application extends JFrame { private JTextField textfield; private Plugin plugin; public Application(Plugin p) { this.plugin=p; p.setapplication(this); init(); protected void init() { JPanel contentpane = new JPanel(new BorderLayout()); public interface Plugin { contentpane.setborder(new BevelBorder(BevelBorder.LOWERED)); String getapplicationtitle(); JButton button = new JButton(); String getbuttontext(); if (plugin!= null) String getinititaltext(); button.settext(plugin.getbuttontext()); void buttonclicked() ; else void setapplication(application app); button.settext("ok"); contentpane.add(button, BorderLayout.EAST); textfield = new JTextField(""); if (plugin!= null) textfield.settext(plugin.getinititaltext()); textfield.setpreferredsize(new Dimension(200, 20)); contentpane.add(textfield, BorderLayout.WEST); if (plugin!= null) button.addactionlistener(/* plugin.buttonclicked(); */); this.setcontentpane(contentpane); public String getinput() { return textfield.gettext(); 30

Taschenrechner public class Application extends JFrame { private JTextField textfield; private Plugin plugin; public Application(Plugin p) { this.plugin=p; p.setapplication(this); init(); protected void init() { JPanel contentpane = new JPanel(new BorderLayout()); public interface Plugin { contentpane.setborder(new BevelBorder(BevelBorder.LOWERED)); String getapplicationtitle(); JButton button = new JButton(); String getbuttontext(); if (plugin!= null) String getinititaltext(); button.settext(plugin.getbuttontext()); void buttonclicked() ; else void setapplication(application app); button.settext("ok"); contentpane.add(button, BorderLayout.EAST); textfield = new JTextField(""); public class CalcPlugin implements Plugin { if (plugin!= null) private Application application; textfield.settext(plugin.getinititaltext()); public void setapplication(application app) { this.application = app; textfield.setpreferredsize(new Dimension(200, public String 20)); getbuttontext() { return "calculate"; contentpane.add(textfield, BorderLayout.WEST); public String getinititaltext() { return "10 / 2 + 6"; if (plugin!= null) public void buttonclicked() { button.addactionlistener(/* JOptionPane.showMessageDialog(null, plugin.buttonclicked(); */); "The result of " this.setcontentpane(contentpane); + application.getinput() + " is " + calculate(application.gettext())); public String getapplicationtitle() { return "My Great Calculator"; public String getinput() { return textfield.gettext(); class CalcStarter { public static void main(string[] args) { new Application(new CalcPlugin()).setVisible(true); 31

public class Application extends JFrame implements InputProvider { private JTextField textfield; private Plugin plugin; public Application(Plugin p) { this.plugin=p; p.setapplication(this); init(); Weitere Entkopplung moeglich public interface InputProvider { String getinput(); protected void init() { JPanel contentpane = new JPanel(new BorderLayout()); public interface Plugin { contentpane.setborder(new BevelBorder(BevelBorder.LOWERED)); String getapplicationtitle(); JButton button = new JButton(); String getbuttontext(); if (plugin!= null) String getinititaltext(); button.settext(plugin.getbuttontext()); void buttonclicked() ; else void setapplication(inputprovider app); button.settext("ok"); contentpane.add(button, BorderLayout.EAST); textfield = new JTextField(""); public class CalcPlugin implements Plugin { if (plugin!= null) private InputProvider application; textfield.settext(plugin.getinititaltext()); public void setapplication(inputprovider app) { this.application = app; textfield.setpreferredsize(new Dimension(200, public String 20)); getbuttontext() { return "calculate"; contentpane.add(textfield, BorderLayout.WEST); public String getinititaltext() { return "10 / 2 + 6"; if (plugin!= null) public void buttonclicked() { button.addactionlistener(/* JOptionPane.showMessageDialog(null, plugin.buttonclicked(); */); "The result of " this.setcontentpane(contentpane); + application.getinput() + " is " + calculate(application.getinput())); public String getapplicationtitle() { return "My Great Calculator"; public String getinput() { return textfield.gettext(); class CalcStarter { public static void main(string[] args) { new Application(new CalcPlugin()).setVisible(true); 32

Plug-ins laden Typisch für viele Frameworks: Plug-in Loader sucht in Verzeichnis nach DLL/Jar/XML Dateien testet ob Datei ein Plug-in implementiert prüft Abhängigkeiten initialisiert Plug-in Häufig zusätzlich GUI für Plugin-Konfiguration Beispiele: Eclipse (plugin-verzeichnis + Jar) Miranda (plugins-verzeichnis + DLL) Alternativ: Plug-ins in Konfigurationsdatei festlegen oder Starter-Programm generieren 33

Beispiel Plugin Loader (benutzt Java Reflection) public class Starter { public static void main(string[] args) { if (args.length!= 1) System.out.println("Plugin name not specified"); else { String pluginname = args[0]; try { Class<?> pluginclass = Class.forName(pluginName); new Application((Plugin) pluginclass.newinstance()).setvisible(true); catch (Exception e) { System.out.println("Cannot load plugin " + pluginname + ", reason: " + e); 34

Mehrere Plug-ins vgl. Observer Pattern Mehrere Plug-ins laden und registrieren Bei Ereignis alle Plug-ins informieren Für unterschiedliche Aufgaben: spezifische Plug-in-Schnittstellen public class Application { private List<Plugin> plugins; public Application(List<Plugin> plugins) { this.plugins=plugins; for (Plugin plugin: plugins) plugin.setapplication(this); public Message processmsg (Message msg) { for (Plugin plugin: plugins) msg = plugin.process(msg);... return msg; 35

Frameworks für Produktlinien Domain Eng. Feature-Modell Mapping von Features zu Plug-ins Framework + Plugins Application Eng. Feature-Auswahl Feature-Auswahl als Eingabe Plug-in-Auswahl (und ggf. Startkonfiguration generieren) Anwendung = Framework mit passenden Plugins 36

Frameworks für Produktlinien Bewertung Vollautomatisierung möglich Modularität Praxiserprobt Erstellungsaufwand und Laufzeit-Overhead für Framework/Architektur Framework-Design erfordert Erfahrung Schwierige Wartung, Evolution Preplanning Problem Grobe Granularität oder riesige Interfaces 37 Plug-in für Transaktionsverwaltung oder gewichtete Kanten? Problem der Querschneidenden Belange

Zusammenfassung Modularisierung von Features mit Komponenten und Frameworks Laufzeitoverhead, grobe Granularität Grenzen bei querschneidenen Belangen und feiner Granularität Modularität erfordert Planung Nicht für alle Produktlinien geeignet (z.b. Graph-Bibliothek, eingebettete Datenbanken) 38

Ausblick Neue Programmierkonzepte Analyse Objekt-Orientierung und deren Grenzen Feature-Orientierung Aspekt-Orientierung 39

Literatur S. Apel, D. Batory, C. Kästner, and G. Saake. Feature-Oriented Software Product Lines - Concepts and Implementation. Springer, 2013. Section 4.3: Frameworks Section 4.4: Components and Services C. Szyperski: Component Software: Beyond Object-Oriented Programming. Addison-Wesley, 1998 [Standardwerk Komponentenorientierte Softwareentwicklung] R. Johnson and B. Foote, Desiging reusable classes, Journal of Object-Oriented Programming, 1(2):22-35, 1988 [OOP Wiederverwendung, insb. Frameworks] L. Bass, P. Clements, R. Kazman, Software Architecture in Practice, Addison-Wesley, 2003 [Architekturgetriebene Produktlinien, typischerweise Frameworks] 40

Softwareproduktlinien - Feature-Orientierung Sven Apel (Universität Passau) Christian Kästner (CMU) Gunter Saake, Thomas Thüm (Universität Magdeburg) 1

Wie Variabilität implementieren? Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. 2 Feature-Auswahl Generator Fertiges Program

Ziele Neuartige Implementierungstechniken Lösen der Probleme: Feature Traceability (inbs. bei Laufzeitvariabilität, Branches, Build-Systemen, Präprozessoren) Querschneidende Belange (inbs. bei Frameworks, Komponenten) Preplanning Problem (inbs. bei Frameworks, Komponenten) Unflexible Vererbungshierarchien (inbs. Bei Laufzeitvariabilität, Frameworks, Komponenten) Modulare Feature-Implementierung 3

Agenda Grundidee Implementierung mit AHEAD Prinzip der Uniformität Modellbildung 4

5 Grundidee

Ziel: Feature-Kohäsion (Feature Traceability Problem) Eigenschaft eines Programms alle Implementierungsartefakte eines Features an einer Stelle im Code zu lokalisieren Features sind explizit im Programmcode Eine Frage der Programmiersprache bzw. der Programmierumgebung! Virtuelle vs. physische Trennung 6

Feature Traceability mit Werkzeugunterstützung Feature-Modell Ein Werkzeug verwaltet die Abbildung Implementierungsartefakte 7

Feature Traceability mit Sprachunterstützung Feature-Modell 1:1 Abbildung (oder zumindest 1:n) Implementierungsartefakte 8

Feature-Orientierte Programmierung Prehofer, ECOOP'97 und Batory, ICSE'03 Sprachbasierter Ansatz zur Überwindung des Feature Traceability Problems Jedes Feature wird durch ein Feature-Modul implementiert Gute Feature Traceability Trennung und Modularisierung von Features Einfache Feature-Komposition Feature-basierte Programmgenerierung 9

Feature-Komposition 10

Feature-Komposition 11

Feature-Komposition 12

Feature-Komposition 13

Produktlinien mit Feature-Modulen Feature-Modell 1:1-Abbildung von Features auf Feature-Module Feature-Module Feature-Auswahl als Eingabe Feature-Auswahl Kompositionswerkzeug Fertiges Program 14

15 Implementierung mit AHEAD

Implementierung von Feature-Modulen Aufteilung in Klassen ist etabliert und als Grundstruktur nutzbar Features werden oft von mehreren Klassen implementiert Klassen implementieren oft mehr als ein Feature Idee: Klassenstruktur prinzipiell beibehalten, aber Klassen aufteilen anhand von Features AHEAD (Algebraic Hierarchical Equations for Application Design) oder FeatureHouse als mögliche Werkzeuge 16

Aufspalten von Klassen Klassen Graph Edge Node Weight Color Search Features Directed Weighted Colored 17

Kollaborationen & Rollen Kollaboration: eine Menge von Klassen, die miteinander interagieren, um ein Feature zu implementieren Verschiedene Klassen spielen verschiedene Rollen innerhalb einer Kollaboration Eine Klasse spielt verschiedene Rollen in verschiedenen Kollaborationen Eine Rolle kapselt das Verhalten/die Funktionalität einer Klasse, welche(s) für eine Kollaboration relevant ist 18

Kollaborationen & Rollen Klassen Graph Edge Node Weight Color Kollaborationen Search Directed Weighted Colored Rollen 19

Auszug: Kollaborationenentwurf class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); return e; void print() { for(int i = 0; i < ev.size(); i++) ((Edge)ev.get(i)).print(); class Edge { Node a, b; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { a.print(); b.print(); class Node { int id = 0; void print() { System.out.print(id); refines class Graph { Edge add(node n, Node m) { Edge e = Super.add(n, m); e.weight = new Weight(); Edge add(node n, Node m, Weight w) Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; refines class Edge { Weight weight = new Weight(); void print() { Super.print(); weight.print(); class Weight { void print() {... 20

Auszug: Verzeichnishierarchie 21

Beispiel: Klassenverfeinerungen Edge.jak class Edge {... Schrittweise Erweiterung der Basisimplementierung durch Verfeinerungen Edge.jak refines class Edge { private Node start;... Ungenaue Definition der Basisimplementierung Edge.jak refines class Edge { private int weight;... 22

Methodenverfeinerungen (AHEAD) Methoden können in jeder Verfeinerung eingeführt oder erweitert werden Überschreiben von Methoden Aufruf der Methode aus vorheriger Verfeinerung mit Super* Ähnlich zu Vererbung * Aus technischen Gründen müssen hinter Super die erwarteten Typen der Methode angegeben werden, z. B. Super(String,int).print('abc', 3) class Edge { void print() { System.out.print( " Edge between " + node1 + " and " + node2); refines class Edge { private Node start; void print() { Super().print(); System.out.print( " directed from " + start); refines class Edge { private int weight; void print() { Super().print(); System.out.print( " weighted with " + weigth); 23

Methodenverfeinerungen (FeatureHouse) Kein refines nötig Methoden können in jeder Verfeinerung eingeführt oder erweitert werden Überschreiben von Methoden Aufruf der Methode aus vorheriger Verfeinerung mit original Ähnlich zu Vererbung class Edge { void print() { System.out.print( " Edge between " + node1 + " and " + node2); class Edge { private Node start; void print() { original(); System.out.print( " directed from " + start); class Edge { private int weight; void print() { original(); System.out.print( " weighted with " + weigth); 24

Produktlinien mit Feature-Modulen Feature-Modell 1:1-Abbildung von Features auf Feature-Module Feature-Module Feature-Auswahl als Eingabe Feature-Auswahl Kompositionswerkzeug Fertiges Program 25

Komposition in AHEAD Konfiguration Composer jampack Komponierte Jak-Dateien Feature-Module (Verzeichnisse) mit Jak-Dateien mixin jak2java Java-Dateien 26

Komposition in FeatureHouse Konfiguration Java-Dateien FeatureHouse Feature-Module (Verzeichnisse) mit Java-Dateien 27

Komposition von Verzeichnissen Alle Rollen einer Kollaboration werden in einem Package/Modul gespeichert, i.d.r. in einem Verzeichnis Komposition von Kollaborationen durch Komposition von Klassen mit allen enthaltenen gleichnamigen Klassenverfeinerungen 28

Beispielkomposition Base Search Directed Weighted Colored Graph Edge Node Weight Color Graph Edge Node Feature-Auswahl in Textdatei (Feature-Namen in Zeilen) 29

Komposition mit Jampack Zusammenbauen zu einer Klasse durch Überlagerung (superimposition) Super/original-Aufrufe werden durch inlining integriert Ergebnis: eine Klasse class Edge { private Node start; private int weight; void print() { System.out.print( " Edge between " + node1 + " and " + node2); System.out.print( " directed from " + start); System.out.print( " weighted with " + weigth); 30

Komposition mit Mixin Generierung einer Klasse pro Rolle mit entsprechender Hierarchie Umbenennung, so dass finale Klasse den Klassennamen erhält Ersetzen von Super durch super class Edge$$Base { void print() {... class Edge$$Directed extends Edge$$Base { private Node start; void print() { super.print(); System.out.print( " directed from " + start); class Edge extends Edge$$Directed{ private int weight; void print() { super.print(); System.out.print( " weighted with " + weigth); 31

Mixin vs. Jampack Jampack Zuordnung von generierten Code zu Rollen verschwindet nach Generierung Mixin Code-Overhead Langsamer, durch Indirektion bei Methodenaufrufen 32

Werkzeuge AHEAD Tool Suite + Dokumentation Kommandozeilenwerkzeuge für Jak (Java 1.4-Erweiterung) http://www.cs.utexas.edu/users/schwartz/ats.html FeatureHouse Kommandozeilenwerkzeug für Java 1.5, C#, C, Haskell, UML http://www.fosd.de/fh FeatureC++ Alternative zu AHEAD für C++ http://www.fosd.de/fcpp FeatureIDE Eclipse-Plugin für AHEAD, FeatureHouse und FeatureC++ Automatisches Bauen, Syntax Highlighting, etc http://www.fosd.de/featureide 33

Zusammenfassung zum AHEAD-Ansatz Eine Basisklasse + beliebige Verfeinerungen (Rollen) Klassenverfeinerungen können Felder einführen Methoden einführen Methoden verfeinern Feature-Modul (Kollaboration): Verzeichnis mit Basisklassen und/oder Verfeinerungen Beim Übersetzem werden Basisklasse + Verfeinerungen der ausgewählten Feature-Module zusammengebaut 35

36 Prinzip der Uniformität

Prinzip der Uniformität Software besteht nicht nur aus Java-Quellcode Andere Programmiersprachen (z. B. C++, Javascript) Build-Skripte (Make, XML) Dokumentation (XML, HTML, PDF, Text, Word) Grammatiken (BNF, ANTLR, JavaCC, Bali) Modelle (UML, XMI,...) Alle Software-Artefakte müssen verfeinert werden können Integration von verschiedenen Artefakten in Kollaborationen 37

Prinzip der Uniformität Features are implemented by a diverse selection of software artifacts and any kind of software artifact can be subject of subsequent refinement. Don Batory Don Batory 38

Beispiel: Prinzip der Uniformität Graph Edge Node Buildfile Doc Base Grap h.jak Edge. jak Node.jak build. xml index.htm Search Grap h.jak Node.jak build. xml index.htm Directed Grap h.jak Edge. jak build. xml index.htm Weighted Grap h.jak Edge. jak build. xml index.htm Colored Node.jak Node.jak build. xml index.htm Weitere Dateien: Grammatiken, Unit-Tests, Modelle, Spezifikationen, u.v.m. 39

Werkzeugunterstüzung AHEAD Konzept sprachübergreifend, separate Tools für: Jak (Java 1.4) Xak (XML) Bali-Grammatiken FeatureHouse sprachübergreifendes Tool, leicht erweiterbar, z. Z. implementiert für: Java 1.5 C# C Haskell JavaCC- und Bali-Grammatiken XML JML (Java Modeling Language) 40

41 Modellbildung

Wozu ein abstraktes Modell? Diskussion bisher hauptsächlich auf Ebene verschiedener Sprachkonstrukte Modell zeigt die gemeinsamen Ideen und ignoriert ablenkende Details Abstrahiert von Details in AHEAD, FeatureHouse oder anderen Sprachen und Tools Ermöglicht die Diskussion von Konzepten unabhängig einer konkreten Programmiersprache ( Prinzip der Uniformität) 42

Wozu ein abstraktes Modell? Erlaubt später neue Operationen auf Features (z. B. Typprüfung oder Interaktionsanalyse) formal und sprachunabhängig zu diskutieren Vereinfacht die Implementierung von Werkzeugen (z. B. Komposition innerer Klassen?) Analyse algebraischer Eigenschaften von Feature-Komposition potentielle Optimierung 43

Feature-Komposition Features können mit anderen Features komponiert werden und bilden so komplexere Features Programme sind selber auch (zusammengesetzte) Features Menge F der Features; Kompositionsoperator (assoziativ, aber nicht kommutativ und nicht idempotent) 44

Features modelliert als Bäume Ein Feature besteht aus einem oder mehreren Code- Artefakten, je mit einer internen Struktur Features werden als Bäume modelliert (Feature Structure Tree FST), welche die Struktur der Artefakte reflektieren package util; class Calc { int e0 = 0, e1 = 0, e2 = 0; void enter(int val) { e2 = e1; e1 = e0; e0 = val; void clear() { e0 = e1 = e2 = 0; String top() { return String.valueOf(e0); e0 util Calc e1 e2 top enter clear 45

Struktur von FSTs Nur die wesentliche Struktur eines Artefakts im FST Beispiel Java: Packages, Klassen, Methoden, und Felder abgebildet Statements, Parameter, Initialwert von Feldern nicht im FST abgebildet Andere Granularität möglich je nach Programmiersprache und Aufgabe wählen 46

Eigenschaften von FSTs Knoten im FST haben einen Namen und einen Typ Ordnung der Kinder kann relevant sein package util; class Calc { int e0 = 0, e1 = 0, e2 = 0; void enter(int val) { e2 = e1; e1 = e0; e0 = val; void clear() { e0 = e1 = e2 = 0; String top() { return String.valueOf(e0); e0 util Calc package class e1 e2 top enter clear field field field method method method 47

Komposition durch Überlagerung von Bäumen package util; class Calc { void add() { e0 = e1 + e0; e1 = e2; feature: Add feature: CalcBase package util; class Calc { int e0 = 0, e1 = 0, e2 = 0; void enter(int val) { e2 = e1; e1 = e0; e0 = val; void clear() { e0 = e1 = e2 = 0; String top() { return String. valueof(e0); = feature: CalcAdd package util; class Calc { int e0 = 0, e1 = 0, e2 = 0; void enter(int val) { e2 = e1; e1 = e0; e0 = val; void clear() { e0 = e1 = e2 = 0; String top() {/*...*/ void add() { e0 = e1 + e0; e1 = e2; util Calc util = Calc util Calc add e0 e1 e2 top enter clear e0 e1 e2 top enter clear add 48

Überlagerung von Bäumen Rekursive Überlagerung (superimposition) der Knoten, beginnend bei der Wurzel Zwei Knoten werden überlagert, wenn...... ihre Vaterknoten überlagert wurden... und beide den gleichen Namen und Typ haben Nach der Überlagerung von zwei Knoten, werden ihre Kinder rekursiv überlagert Wenn zwei Knoten nicht überlagert wurden, werden sie beide dem Ergebnisbaum an entsprechender Stelle hinzugefügt 49

Terminal- und Nichtterminalknoten Nichtterminalknoten Transparente Knoten Können Kinder haben Name und Typ, aber keinen weiteren Inhalt Können problemlos überlagert werden Terminalknoten Haben keine Kinder Name und Typ Können weiteren Inhalt haben, Überlagerung daher nicht trivial 50

Feature-Komposition Rekursive Komposition der FST-Elemente package package package (auch für Unterpakete) class class class (auch für innere Klassen) method method? field field? 51

Überlagerung von Terminalknoten Option 1: Zwei Terminalknoten mit gleichem Namen und Typ können nie überlagert werden Option 2: Zwei Terminalknoten mit gleichem Namen und Typ können unter bestimmten Umständen überlagert werden method method method, falls eine Methode die andere erweitert, z. B. indem sie Super oder original aufruft field field field, falls min. ein Attribut keinen Initialwert hat 52

Komposition von Terminalknoten class Calc { int count = 0; void enter(int val) { original(val); count++; class Calc { int count; void enter(int val){ = e2 = e1; e1 = e0; e0 = val; class Calc { int count = 0; void enter(int val) { e2 = e1; e1 = e0; e0 = val; count++;... Calc... = Calc... Calc enter count enter count enter count 53

Bedingungen durch bisheriges Modell Die Struktur eines Features muss hierarchisch sein (Baumstruktur) Jedes Strukturelement muss einen Namen und einen Typ haben Ein Element darf nicht zwei Kinder mit dem gleichen Namen und dem gleichen Typ haben Elemente, die keine hierarchische Unterstruktur haben (Terminale) müssen eine spezielle Kompositionsregel angeben oder können nicht komponiert werden 54

Welche Sprachen können mittels FSTs modelliert werden? Objektorientierte Sprachen erfüllen meist die Bedingungen Einige andere Sprachen, u. a. Grammatiken, erfüllen die Bedingungen auch Sprachen, welche die Bedingungen nicht erfüllen gelten als nicht feature-ready, da sie nicht ausreichend Struktur aufweisen Einige Sprachen können mit zusätzlicher Struktur angereichert werden, z. B. XML 55

FeatureHouse FeatureHouse entstand aus der Formalisierung 56

FeatureHouse Java FSTs Java Parser = Pretty Printer C# C# Parser = Pretty Printer 57 C Haskell Parser Parser = = Pretty Printer Pretty Printer C Haskell

Perspektiven der Modellbildung Diskussion von Sprachmitteln unabhängig einer spezifischen Sprache, z. B. Was würde es bedeuten wenn ein Feature in einer Komposition mehrfach vorkommen kann (z. B. X Y X)? Wie können wir Komposition von Strukturen erreichen, bei dem die Reihenfolge der Kinder wichtig ist (z. B. XML)? Unter welchen Voraussetzungen ist Feature-Komposition kommutativ? Wie können wir eine Sprache feature-ready gestalten (insb. Definition von Sprachmechanismen für Terminalüberlagerung)? Was passiert wenn wir das Löschen von Methoden erlauben wollen? 58

Zusammenfassung Feature-orientierte Programmierung löst u.a. das Feature-Traceability-Problem durch Kollaborationen und Rollen (1:1-Abbildung) Implementierung mittels Klassenverfeinerungen Prinzip der Uniformität Modell auf Basis von Feature Structure Trees 59

Ausblick Implementierung von querschneidenden Belangen kann in bestimmten Fällen sehr aufwendig sein Features sind nicht immer unabhängig. Wie implementiert man abhängige Kollaborationen? Bewertung / Abgrenzung 60

Literatur S. Apel, D. Batory, C. Kästner, and G. Saake. Feature-Oriented Software Product Lines - Concepts and Implementation. Springer, 2013. Section 6.1: Feature-Oriented Programming D. Batory, J. N. Sarvela, and A. Rauschmayer. Scaling Step-Wise Refinement. IEEE Transactions on Software Engineering, 30(6), 2004. [Vorstellung von AHEAD] S. Apel, C. Kästner, and C. Lengauer. Language-Independent and Automated Software Composition: The FeatureHouse Experience. IEEE Transactions on Software Engineering, 39(1), 2013. [Überblick über FSTs und FeatureHouse] S. Apel, C. Lengauer, B. Möller, and C. Kästner. An Algebraic Foundation for Automatic Feature-Based Program Synthesis. Science of Computer Programming, 75(11), 2010. [Formalisierung & Feature-Algebra] 61

Softwareproduktlinien - Aspektorientierung Sven Apel (Universität Passau) Christian Kästner (CMU) Gunter Saake, Thomas Thüm (Universität Magdeburg)

Agenda Grundlagen Reflektion Metaobjektprotokolle Aspektorientierte Programmierung: Ideen und Konzepte AspectJ Grundlagen Join-Point-Modell Entwicklungsumgebung AJDT Diskussion 2

Reflektion Grundlegende Idee Ein Programm hat eine Sicht auf sich selbst Objekte werden durch Klassen beschrieben, Klassen durch Metaklassen und Metaklassen durch Metametaklassen Das Programm kann sich selbst verändern, indem es seinen Code ändert Code wird durch Metadaten repräsentiert 3

Metaobjekt-Protokolle (MOP) Programme können auf Metaebene manipuliert werden, um ihre Struktur und ihr Verhalten zu ändern Verhaltensänderungen funktionieren Ereignis-basiert: wenn das Ereignis X eintritt (z. B. Methode Y wird aufgerufen), führe Code Z aus Bekannt aus LISP; in Standard-Java nicht möglich 4

Modularisierung querschneidender Belange mit Aspekten 6

Idee Modularisierung von einem querschneidenen Belang in einem Aspekt Dieser Aspekt beschreibt die Änderungen dieses Belangs in der restlichen Software Interpretation als Programmtransformation, als Meta- Objekt-Protokoll oder als Feature-Modul möglich Klassen Aspekt Graph Edge Node Weighted Erweiterungen 7

AspectJ Grundlagen Join-Point-Modell 8

AspectJ AspectJ ist eine AOP-Erweiterung für Java Aspekte werden ähnlich wie Klassen implementiert, aber es gibt ein Reihe neuer Sprachkonstrukte Der Basiscode wird weiterhin in Java implementiert Aspekte werden von einem speziellen Aspekt-Compiler in den Code gewebt 9

Was kann ein Aspekt? Ein Aspekt in Programmiersprachen wie AspectJ kann Klassenhierarchien manipulieren Methoden und Felder zu einer Klasse hinzufügen Methoden mit zusätzlichem Code erweitern Ereignisse wie Methodenaufrufe oder Feldzugriffe abfangen und zusätzlichen oder alternativen Code ausführen 10

Statische Erweiterungen Statische Erweiterungen mit Inter-Typ-Deklarationen z. B. füge Methode X in Klasse Y ein aspect Weighted { private int Edge.weight = 0; public void Edge.setWeight(int w) { weight = w; 11

Dynamische Erweiterungen Dynamische Erweiterungen auf Basis des Join-Point- Modells Ein Ereignis in der Programmausführung, wie ein Methodenaufruf, ein Feldzugriff o.a., wird als (dynamischer) Join-Point bezeichnet Ein Pointcut ist ein Prädikat um Join-Points (JPs) auszuwählen Advice ist Code, der ausgeführt wird, wenn ein JP von einem Pointcut ausgewählt wurde aspect Weighted {... pointcut printexecution(edge edge) : execution(void Edge.print()) && this(edge); after(edge edge) : printexecution(edge) { System.out.print(' weight ' + edge.weight); 12

Quantifizierung Eine wichtige Eigenschaft von Pointcuts ist, dass sie deklarativ Join-Points quantifizieren und mehrere auswählen können Beispiele: Führe Advice X immer aus, wenn die Methode setweight in Klasse Edge aufgerufen wird Führe Advice Y immer aus, wenn auf irgendein Feld in der Klasse Edge zugegriffen wird Führe Advice Z immer aus, wenn irgendwo im System eine öffentliche Methode aufgerufen wird, und vorher die Methode initialize aufgerufen wurde 13

AspectJ Join Point Model Join Points treten auf bei(m) Aufruf einer Methode Ausführung einer Methode Aufruf eines Konstruktors Ausführung eines Konstruktors Zugriff auf ein Feld (lesend oder schreibend) Fangen einer Exception Initialisierung einer Klasse oder eines Objektes Ausführen von Advice 14

Join Point Beispiel field access (set) field access (get) class Test { MathUtil u; public void main() { u = new MathUtil(); int i = 2; i = u.twice(i); System.out.println(i); class MathUtil { public int twice(int i) { return i * 2; method-execution constructor call method-call method-call method-execution 15

Pointcut execution Erfasst die Ausführung einer Methode aspect A1 { after() : execution(int MathUtil.twice(int)) { System.out.println("MathUtil.twice executed"); class Test { public static void main(string[] args) { MathUtil u = new MathUtil(); int i = 2; i = u.twice(i); System.out.println(i); class MathUtil { Ausführung public int twice(int i) { return i * 2; Syntax: execution(returntype ClassName.Methodname(ParameterTypes)) 16

Explizite und Anonyme Pointcuts aspect A1 { after() : execution(int MathUtil.twice(int)) { System.out.println("MathUtil.twice executed"); aspect A2 { pointcut executetwice() : execution(int MathUtil.twice(int)); after() : executetwice() { System.out.println("MathUtil.twice executed"); 17

Advice Zusätzlicher Code vor (before), nach (after) oder anstelle (around) des Join-Points Bei around-advice ist es möglich den originalen Join- Point mittels des Schlüsselworts proceed fortzusetzen 18

Advice II public class Test2 { void foo() { System.out.println("foo() executed"); aspect AdviceTest { before(): execution(void Test2.foo()) { System.out.println("before foo()"); after(): execution(void Test2.foo()) { System.out.println("after foo()"); void around(): execution(void Test2.foo()) { System.out.println("around begin"); proceed(); System.out.println("around end"); after() returning (): execution(void Test2.foo()) { System.out.println("after returning from foo()"); after() throwing (RuntimeException e): execution(void Test2.foo()) { System.out.println("after foo() throwing "+e); 19

thisjoinpoint In Advice kann thisjoinpoint verwendet werden, um mehr Informationen über den aktuellen Join Point zu ermitteln aspect A1 { after() : call(int MathUtil.twice(int)) { System.out.println(thisJoinPoint); System.out.println(thisJoinPoint.getSignature()); System.out.println(thisJoinPoint.getKind()); System.out.println(thisJoinPoint.getSourceLocation()); Ausgabe: call(int MathUtil.twice(int)) int MathUtil.twice(int) method-call Test.java:5 20

Muster Erlaubt unvollständige Angabe des Ziels zur Quantifizierung aspect Execution { pointcut P1() : execution(int MathUtil.twice(int)); pointcut P2() : execution(* MathUtil.twice(int)); pointcut P3() : execution(int MathUtil.twice(*)); pointcut P4() : execution(int MathUtil.twice(..)); pointcut P5() : execution(int MathUtil.*(int,..)); pointcut P6() : execution(int *Util.tw*(int)); * als Platzhalter für einen Wert.. als Platzhalter für 0 oder mehr Werte pointcut P7() : execution(int *.twice(int)); pointcut P8() : execution(int MathUtil+.twice(int)); + für Subklassen pointcut P9() : execution(public int package.mathutil.twice(int) throws ValueNotSupportedException); pointcut Ptypisch() : execution(* MathUtil.twice(..)); 21

Pointcut call Erfasst den Aufruf einer Methode Ähnlich zu execution, aber auf Aufruferseite aspect A1 { after() : call(int MathUtil.twice(int)) { System.out.println("MathUtil.twice called"); Ausführung Ausführung class Test { public static void main(string[] args) { MathUtil u = new MathUtil(); int i = 2; i = u.twice(i); i = u.twice(i); System.out.println(i); class MathUtil { public int twice(int i) { return i * 2; 22

Konstruktoren new als spezielle Methode aspect A1 { after() : call(mathutil.new()) { System.out.println("MathUtil created"); class Test { public static void main(string[] args) { Ausführung MathUtil u = new MathUtil(); int i = 2; i = u.twice(i); i = u.twice(i); System.out.println(i); class MathUtil { public int twice(int i) { return i * 2; 23

Pointcuts set & get Erfasst den Zugriff auf ein Feld (Instanzvariable) aspect A1 { after() : get(int MathUtil.counter) { System.out.println("MathUtil.value read"); aspect A1 { after() : set(int MathUtil.counter) class { Test { System.out.println("MathUtil.value set"); set(int MathUtil.counter) set(int MathUtil.*) set(* *.counter) Ausführung public static void main(string[] args) { MathUtil u = new MathUtil(); int i = 2; i = u.twice(i); i = u.twice(i); System.out.println(i); class MathUtil { public int twice(int i) { return i * 2; 24

Pointcut args Matched nur die Parameter einer Methode Ähnlich zu execution(* *.*(X, Y)) oder call(* *.*(X, Y)) aspect A1 { after() : args(int) { System.out.println("A method with only one parameter " + "of type int called or executed"); args(int) args(*) args(object, *, String) args(.., Buffer) Ausführung Ausführung Ausführung Ausführung class Test { public static void main(string[] args) { MathUtil u = new MathUtil(); int i = 2; i = u.twice(i); i = u.twice(i); System.out.println(i); class MathUtil { public int twice(int i) { return i * 2; 25

Kombination von Pointcuts Pointcuts können mit &&, und! verbunden werden aspect A1 { pointcut P1(): execution(* Test.main(..)) call(* MathUtil.twice(*)); pointcut P2(): call(* MathUtil.*(..)) &&!call(* MathUtil.twice(*)); pointcut P3(): execution(* MathUtil.twice(..)) && args(int); 26

Parametrisierte Pointcuts Pointcuts können Parameter haben, die in Advice genutzt werden können Damit erhält der Advice Informationen zum Kontext Der Pointcut args wird dazu mit einer Variablen, statt mit einem Typ, verwendet aspect A1 { pointcut exectwice(int value) : execution(int MathUtil.twice(int)) && args(value); after(int value) : exectwice(value) { System.out.println("MathUtil.twice executed with parameter " + value); aspect A1 { after(int value) : execution(int MathUtil.twice(int)) && args(value) { System.out.println("MathUtil.twice executed with parameter " + value); 27

Advice nutzt Parameter Beispiel für Advice der Parameter nutzt und ändert: aspect DoubleWeight { pointcut setweight(int weight) : execution(void Edge.setWeight(int)) && args(weight); void around(int weight) : setweight(weight) { System.out.print('doubling weight from ' + weight); try { proceed(2 * weight); finally { System.out.print('doubled weight from ' + weight); 28

Pointcuts this und target this und target erfassen die involvierten Klassen Können mit Typen (inkl. Muster) und mit Parametern genutzt werden aspect A1 { pointcut P1(): execution(int *.twice(int)) && this(mathutil); pointcut P2(MathUtil m) : execution(int MathUtil.twice(int)) && this(m); pointcut P3(Main source, MathUtil target): call(* MathUtil.twice(*)) && this(source) && target(target); Bei execution: this und target erfassen das Objekt auf dem die Methode aufgerufen wird Bei call, set und get: this erfasst das Objekt, das die Methode aufruft oder auf das Feld zugreift; target erfasst das Objekt, auf dem die Methode aufgerufen oder auf das Feld zugegriffen wird 29

Pointcuts Within und Withincode Schränken Join-Points nach Ort des Vorkommens ein Beispiel: nur Aufrufe zur twice Methode, die aus Test bzw. Test.main kommen aspect A1 { pointcut P1(): call(int MathUtil.twice(int)) && within(test); pointcut P2(): call(int MathUtil.twice(int)) && withincode(* Test.main(..)); 30

Pointcuts cflow und cflowbelow Erfasst alle Join-Points. die im Kontrollfluss eines anderen Join-Points stattfinden aspect A1 { pointcut P1(): cflow(execution(int MathUtil.twice(int))); pointcut P2(): cflowbelow(execution(int MathUtil.twice(int))); 31

Kontrollfluss class Test { public static void main() { MathUtil u = new MathUtil(); int i = 2; i = u.twice(i); i = u.twice(i); i = u.power(i, 3); System.out.println(i); Stack: Test.main MathUtil.twice MathUtil.power MathUtil.power MathUtil.power MathUtil.power class MathUtil { public int twice(int i) { return i * 2; public int power(int i, int j){ if (j == 0) return 1; return i * power(i, j - 1); 32

Beispiele zu cflow before() : execution(* *.*(..)) execution(* *.*(..)) && cflow(execution(* *.power(..))) execution(void Test.main(String[])) execution(int MathUtil.twice(int)) execution(int MathUtil.twice(int)) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) execution(* *.*(..)) && cflowbelow(execution(* *.power(..))) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) execution(* *.power(..)) &&!cflowbelow(execution(* *.power(..))) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) execution(int MathUtil.power(int, int)) 33

Aspektweben Wie werden Aspekte ausgeführt? MOP und interpretierte Sprachen: zur Laufzeit ausgewertet AspectJ/AspectC++/ : einweben des Aspektes durch den Compiler Einweben: 34 Inter-Typ-Deklarationen werden in die entsprechenden Klassen eingefügt Advice wird in Methoden umgewandelt Pointcuts: Methodenaufruf von den Join-Points zum Advice hinzufügen Dynamische Erweiterungen: an allen potentiellen Join-Points Quelltext einfügen, der dynamische Bedingung prüft und ggf. Methodenaufruf zum Advice ausführt

Aspekte im Graph-Beispiel Basic Graph class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); return e; void print() { for(int i = 0; i < ev.size(); i++) ((Edge)ev.get(i)).print(); class Edge { Node a, b; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { a.print(); b.print(); class Node { int id = 0; void print() { System.out.print(id); Color aspect ColorAspect { Color Node.color = new Color(); Color Edge.color = new Color(); before(node c) : execution(void print()) && this(c) { Color.setDisplayColor(c.color); before(edge c) : execution(void print()) && this(c) { Color.setDisplayColor(c.color); static class Color {... 35

Aspekte im Graph-Beispiel Basic Graph class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); return e; void print() { for(int i = 0; i < ev.size(); i++) ((Edge)ev.get(i)).print(); class Edge { Node a, b; Edge(Node _a, Node _b) { a = _a; b = _b; void print() { a.print(); b.print(); class Node { int id = 0; void print() { System.out.print(id); Color aspect ColorAspect { static class Colored { Color color; declare parents: (Node Edge) extends Colored; before(colored c) : execution(void print()) && this(c) { Color.setDisplayColor(c.color); static class Color {... 36

Typische Aspekte Logging, Tracing, Profiling Fügt identischen Code zu sehr vielen Methoden hinzu aspect Profiler { /** record time to execute my public methods */ Object around() : execution(public * com.company..*.* (..)) { long start = System.currentTimeMillis(); try { return proceed(); finally { long end = System.currentTimeMillis(); printduration(start, end, thisjoinpoint.getsignature()); // implement recordtime... 37

Typische Aspekte II Caching, Pooling Cache oder Resourcenpool zentral implementieren, der an mehreren Stellen wirken kann aspect ConnectionPooling {... Connection around() : call(connection.new()) { if (enablepooling) if (!connectionpool.isempty()) return connectionpool.remove(0); return proceed(); void around(connection conn) : call(void Connection.close()) && target(conn) { if (enablepooling) { connectionpool.put(conn); else { proceed(); 38

Typische Aspekte III Observer Verschiedene Ereignisse sammeln Auf verschachtelte Ereignisse nur einmal reagieren (cflowbelow) abstract class Shape { abstract void moveby(int x, int y); class Point extends Shape {... class Line extends Shape { Point start, end; void moveby(int x, int y) { start.moveby(x,y); end.moveby(x,y); aspect DisplayUpdate { pointcut shapechanged() : execution(void Shape+.moveBy(..)); after() : shapechanged() &&!cflowbelow(shapechanged()) { Display.update(); 39

Typische Aspekte IV Policy Enforcement Policy wird extern implementiert Beispiel: Autosave alle 5 Aktionen aspect Autosave { int count = 0; after(): call(* Command+.execute(..)) { count++; after(): call(* Application.save()) call(* Application.autosave()) { count = 0; before(): call (* Command+.execute(..)) { if (count > 4) Application.autosave(); 40

Fortgeschrittene Konzepte Methoden in Aspekten Reihenfolge beim Aspektweben Wiederverwendung mit abstrakten Aspekten 41

Aspektmethoden Aspekte können wie normale Klassen auch Methoden und Felder enthalten; diese können mit Inter-Typ- Deklarationen, Pointcuts und Advice gemischt werden Advice wird im Kontext des Aspekts ausgeführt, nicht im Kontext der erweiterten Klasse ( third person perspective ) aspect Logging { PrintStream loggingtarget = System.out; private void log(string logstr) { loggingtarget.println(logstr); pointcut anysetmethodcall(object o) : call(public *.set*(..)) && target(o); after(object o) : anysetmethodcall(o) { log('a public method was called on '+ o.getclass().getname()); 42

Aspektrangordnung I Engl. aspect precendence Wenn nicht explizit definiert, ist die Reihenfolge, in der Aspekte gewebt werden, undefiniert Wenn mehrere Aspekte den gleichen Join-Point erweitern kann die Reihenfolge aber relevant sein Beispiel: Erster Aspekt implementiert Synchronisierung mit around-advice, zweiter Aspekt implementiert Logging mit after-advice auf dem gleichen Join-Point; Je nach Reihenfolge des Webens wird der Logging-Code synchronisiert oder nicht 43

Aspektrangordnung II Möglichkeit explizit eine Rangfolge festzulegen mittels declare precedence aspect DoubleWeight { declare precedence : *, Weight, DoubleWeight;... Aspekt mit höchster Priorität wird zuerst gewebt, d. h. bei before wird der Advice aus diesem Aspekt zuerst ausgeführt, bei after zuletzt, bei around als äußerstes 44

Advice-Rangordnung Falls mehrere Advice-Statements in dem gleichen Aspekt einen Join-Point erweitern, ist die Reihenfolge durch die Anordnung deren Definition in dem Aspekt festgelegt 45

Abstrakte Aspekte Aspekte unterstützen eine einfache Form der Vererbung, um sie wiederverwendbar zu machen Wie Klassen können Aspekte als abstrakt deklariert werden. Abstrakte Aspekte können abstrakte Pointcuts enthalten, die erst in einem Sub-Aspekt definiert werden. Aspekte können nur von abstrakten Aspekten erben, nicht von konkreten Aspekten Überschreiben von Pointcuts ist möglich, überschreiben von Advice aber nicht, weil Advice anonym ist 46

Beispiel: Aspekt-Wiederverwendung abstract aspect AbstractLogger { abstract pointcut loggingpointcut(); PrintStream loggingtarget = System.out; protected void log(string logstr) { loggingtarget.println(logstr); after() : loggingpointcut() { log('join point reached ' + thisjoinpoint); aspect PrintLogger extends AbstractLogger { pointcut loggingpointcut() : execution(* print*(..)); aspect SetLogger extends AbstractLogger { pointcut loggingpointcut() : execution(* set*(..)); protected void log(string logstr) { super.log('set Method: ' + logstr); 47

Entwicklungsumgebung AJDT Eclipse-Plugin für AspectJ Entwicklung Integriert Aspekte in Eclipse, wie Java in JDT Compiler und Debugger Integration Syntax Highlighting, Outline Links zwischen Aspekten und erweiterten Stellen (zeigt an wo der Quelltext von Aspekten erweitert wird) 48

AJDT in Aktion 49

AJDT in Aktion 50

51 Diskussion

Unbewusstheitsprinzip I Unbewusstheitsprinzip (obliviousness) besagt, dass das Basisprogramm nichts von den Aspekten wissen muss: Programmiere einfach Java wie immer, wir fügen die Aspekte später hinzu Bedeutet, dass klassisches OO-Design reicht, der Quelltext muss nicht für Aspekte vorbereitet werden ( schreibe einfach die Datenbank ganz normal, wir fügen Transaktionen später hinzu ) Basisentwickler brauchen keine Kenntnisse über Aspekte, wenige Spezialisten reichen die AOP-Sprache sehr mächtig sein muss 52

Unbewusstheitsprinzip II Unbewusstheitsprinzip wurde neben Quantifizierung als zweites Merkmal von AOP vorgeschlagen Sehr kontrovers, weil...... Programmierer den Basisquelltext ändern können, ohne Aspekte wahrzunehmen und anzupassen ( Fragile Pointcut Problem ; keine expliziten Schnittstellen)... teils sehr schlechtes Design die Konsequenz ist, wenn die Aspekte nicht beim Entwurf berücksichtigt werden, sondern später reingehackt werden... dann typischerweise komplexe Sprachmittel wie cflow oder call && within code verwendet werden, um Erweiterungen in unvorbereitetem Quelltext dennoch auszudrücken 53

Warum eigentlich Aspekte? Erlauben kohäsive Implementierung von querschneidenden Belangen Erlauben deklarativ über viele Join-Points zu quantifizieren (homogene Erweiterungen an vielen Punkten im Programm) Erlauben Analysen dynamischer Eigenschaften wie des Kontrollfluss (cflow), die in OOP erhebliche Workarounds benötigen 54

Aspekte für Features? Aspekte sind sehr ähnlich zu Kollaborationen Können Code statisch einfügen Können Methoden erweitern Können darüber hinaus sogar homogene Erweiterungen und Erweiterungen auf Basis des dynamischen Kontrollfluss Aspekte können ein und ausgeschaltet werden, indem man sie mit dem Programm kompiliert, oder nicht Manuell in Eclipse: Rechtsklick auf Aspekt und Exclude from Buildpath Automatisiert mit Buildsystem FeatureIDE in Kombination mit AJDT 55

Produktlinien mit Aspekten Feature-Modell 1:1 Mapping von Features zu Aspekten Java-Programm + Aspekte Feature-Auswahl als Eingabe AspectJ-Compiler Feature-Auswahl Kompiliert mit ausgewählten Aspekten Fertiges Program 56

Aspekte für Features? Pro Feature ein Aspekt? Aspekte können sehr groß und unübersichtlich werden Aspekte können neue Klassen nur als statische innere Klassen einfügen Daher: Bündelung von mehreren Aspekten und Klassen in Feature-Modulen möglich 57

Probleme Lexikalische Vergleiche / Fragile Pointcut Problem / Komplexe Syntax 58

Pointcuts nutzen lexikalische Vergleiche Pointcuts wählen Join-Points aufgrund von Namensvergleichen, obwohl Methodennamen eigentlich frei gewählt werden können Musterausdrücke nutzen Namenskonventionen aus, z. B. get*, draw* usw. class Chess { void drawking() {... void drawqueen() {... void drawknight() {... aspect UpdateDisplay { pointcut drawn : execution(* draw*(..));... 59

Fragile Pointcut Problem / Evolution Paradox Wenn der Basiscode geändert wird, kann es passieren, dass neue Join-Points von einem existierenden Pointcut erfasst werden, oder bisherige Join-Points nicht mehr erfasst werden Schachbeispiel: Ein Entwickler, der den Aspekt nicht kennt, fügt eine Methode für Unentschieden hinzu void draw() Solche Änderungen im Programmverhalten können unbemerkt stattfinden, es ist aufwendig herauszukriegen, ob die korrekten Pointcuts erfasst wurden 60 draw = zeichnen draw = Unentschieden

Komplexe Syntax AspectJ ist sehr mächtig und biete viele Ausdrucksmöglichkeiten mit vielen Sprachkonstrukten Die Sprache wird dadurch komplex, insbesondere einfache Erweiterungen sind aufwendig z. B. einfache Methodenerweiterungen: OOP / FOP public void delete(transaction txn, DbEntry key) { super.delete(txn, key); Tracer.trace(Level.FINE, "Db.delete", this, txn, key); AOP pointcut tracedel(database db, Transaction txn, DbEntry key) : execution(void Database.delete(Transaction, DbEntry)) && args(txn, key) && within(database) && this(db); after(database db, Transaction txn, DbEntry key): tracedel(db, txn, key) { Tracer.trace(Level.FINE, "Db.delete", db, txn, key); 61

Zusammenfassung Aspektorientierte Programmierung beschreibt Änderungen deklarativ und quantifiziert über das Programm AspectJ als AOP-Erweiterung von Java; AJDT als Entwicklungsumgebung Konzepte: Join-Point, Inter-Typ-Deklaration, Pointcut, Advice 76

Literatur I S. Apel, D. Batory, C. Kästner, and G. Saake. Feature- Oriented Software Product Lines - Concepts and Implementation. Springer, 2013. Section 6.2: Aspect-Oriented Programming eclipse.org/aspectj, eclipse.org/ajdt R. Laddad. AspectJ in Action: Practical Aspect-Oriented Programming. Manning Publications, 2003. [Praktisches Buch zu AspectJ mit vielen Anwendungsbeispielen] 77

Literatur II R.E. Filman and D.P. Friedman, Aspect-Oriented Programming is Quantification and Obliviousness, In Workshop on Advanced Separation of Concerns, OOPSLA 2000 [Versuch einer Definition für AOP] S. Apel, C. Lengauer, B. Möller, and C. Kästner. An Algebraic Foundation for Automatic Feature-Based Program Synthesis. Science of Computer Programming, 2010. [Modellbildung & Feature-Algebra] 78

Literatur III Für historisch Interessierte, hier die Originalpublikationen: G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C. V. Lopes, J.- M. Loingtier, and J. Irwin. Aspect-Oriented Programming. In Proc. Europ. Conf. on Object-Oriented Programming (ECOOP), 1997 [Originalpaper, das die Problematik beschreibt und AOP als Lösung vorschlägt] G. Kiczales, E. Hilsdale, J. Hugunin, M. Kersten, J. Palm, and W. G. Griswold. An Overview of AspectJ. In Proc. Europ. Conf. on Object-Oriented Programming (ECOOP), 2001 [Erste Vorstellung von AspectJ als Sprache] 79

Softwareproduktlinien - Feature-Interaktionen Christian Kästner (CMU) Sven Apel (Universität Passau) Gunter Saake, Thomas Thüm (Universität Magdeburg)

Einführung Bisher nicht betrachtet: Was passiert wenn Features nicht unabhängig sind? Wie interagieren Features? Wie bewahrt man Variabilität trotz Abhängigkeiten? Wieviel Variabilität ist sinnvoll? 2

Agenda Feature-Interaktionen und deren Probleme Lösungen für Feature-Interaktionen Diskussion: Variabilität in der Praxis 3

4 Feature-Interaktionen

Feature-Interaktionen 1 Telefonproduktlinie: Manche Telefone unterstützen Anklopfen, andere Rufumleitung bei Besetzt Was passiert wenn beide Features aktiviert sind? Freie Leitung: kein Problem Besetzte Leitung: anklopfen oder umleiten? Kann man solche Probleme erkennen? 5

Feature-Interaktionen 2 Flood Control Verhindert Überschwemmung durch Wasser abstellen Fire Control Bekämpft Feuer mit Sprinkleranlage 6

Feature-Interaktionen 3 GPL E DGES S EARCH U NDIRECTED D IRECTED W EIGHTED BFS DFS A LGORITHMS Cycle braucht DFS Shortest Path geht nur auf gewichteten Graphen Connected geht nur auf ungerichteten Graphen Strongly Connected geht nur auf gerichteten Graphen und braucht DFS 7 S INGLE - S OURCE S HORTEST P ATH C ONNECTED C OMPONENTS C YCLE C HECKING S TRONGLY C ONNECTED C. T RANSPOSE

Feature-Interaktionen 4 Datenbank-Produktlinie mit Feature Statistics und Transactions Statistik: sammelt Statistiken über Buffer Hit Ratio, Tabellen-Größe, Transaktionen Transaktionen: Sicherstellung ACID-Eigenschaften Beide Features sollen optional sein Statistics Database Transactions Aber: Statistik sammelt Informationen über Transaktionen, Transaktionen nutzen evtl. statistische Informationen... Wie implementieren, so dass alle Varianten möglich sind? 8

Feature-Interaktionen 5 Datenbank-Produktlinie mit Feature Index und Update Index: beschleunigt den Zugriff durch B-Baum Update: Erlaubt Updates der Datenbank, sonst nur Lesezugriff Beide Features sollen optional sein Effizienter Leseindex Schreiben in Datenbank ohne Index Aber: wenn beide Features schreiben auch in Index Wie implementieren, so dass alle Varianten möglich sind? 9

Interaktionen verursachen Abhängigkeiten Features benutzen Methoden anderer Features Cycle nutzt die Suchfunktion Graph.search, die in DFS eingeführt wurde Shorted Path erwartet, dass die Methode Edge.getWeight vorhanden ist Features erweitern andere Features Feature Weighted implementiert Gewichte indem es Methode addedge aus Base überschreibt Features verlassen sich auf ein bestimmtes Verhalten, welches in einem Feature festgelegt wird Connected erwartet das Kanten immer in beide Richtungen zeigen 11

Problem optionaler Features Optionales Feature verhält sich isoliert korrekt Problem in Kombination mit anderem Feature Zusätzlicher Quelltext koordiniert richtiges Verhalten Transaktionen Statistiken Statistiken über Transaktionen Anklopfen + + Rufumleitung Einstellungsmöglichkeit Index Update + Schreiben in Index 12

Problem optionaler Features: Transaktionen und Statistiken Statistiken (buffer hit ratio, table size and cardinality, ) Transaktionen (locks, commit, rollback, ) Durchsatz-Messung ( Transaktionen pro Sekunde ) 13

Erwünschte Produkte Datenbank mit Statistiken und mit Transaktionen Datenbank mit Statistiken, aber ohne Transakt. Datenbank mit Transakt., aber ohne Statistiken 14

Unerwünschte/Unmögliche Produkte Datenbank mit Transaktionen und ohne Statistiken, die aber denoch den Durchsatz misst (Grösser und langsamer als nötig) Datenbank mit Statistiken und ohne Transaktionen, die dennoch den Durchsatz misst (?) 15

Implementierungbeispiel class Database { List locks; void lock() { /*...*/ void unlock() { /*...*/ void put(object key,object data){ lock(); /*...*/ unlock(); Object get(object key) { lock(); /*...*/ unlock(); int getopenlocks() { return locks.size(); int getdbsize() { return calculatedbsize(); static int calculatedbsize() { lock(); /*...*/ unlock(); Sperren (blau) Statistiken (rot) Die Features überlappen sich an 2 Stellen (violett) Statistiken über Locks Synchronisierung der Statistikmethode 16

Aufteilung in Module? Stat DB Lock Wo implementiert man hier die Durchsatz-Messung? Wie erstellt man ein Produkt mit Statistiken aber ohne Transaktionen? Stat DB Lock Database Statistics Txn-Stats Transactions Stat DB LockStat Ist Durchsatz-Messung wirklich ein Feature? Lock 17

Variabilität Beschreibt wie viele Produkte aus einer Produktlinie erstellt werden können Eine Produktlinie mit n unabhängigen, optionalen Features erlaubt 2 n Produkte Abhängigkeiten zwischen Features schränken die Variabilität der Produktlinie ein Eine einzige Abhängigkeit Feature A benötigt B reduziert die Anzahl der möglichen Produkte um 25% 18

Eingeschränkte Variabilität durch unpassende Modularisierung Feature Modell Implementierung Database Statistics Transactions Mapping DB Stat Lock Gewollt: 4 Produkte Database Eingeschränkte Variabilität Tatsächlich möglich: 3 Produkte DB Index Access Statistics Transactions Mapping Idx Wrt Stat Lock Read Write Gewollt: 12 Produkte Tatsächlich möglich: 5 Produkte 19

Erfahrung: Berkeley DB I Java-Version Feature-Modell 38 Features 16 Domänenabh. 3.6 Milliarden Varianten Implementierung 53 Implementierungsabh. (eingeschr. Variabilität!) C-Version Feature-Modell 24 Features 8 Domänenabh 1 Millionen Varianten Implementierung 78 Implementierungsabh. (eingeschr. Variabilität!) 20

Erfahrung: Berkeley DB II 21

Abhängigkeiten sind transitiv A benötigt B, B benötigt C A benötigt B und C Folge: Einzelne Features können die Auswahl vieler weiterer Features erzwingen und die Variabilität der SPL deutlich einschränken Beispiel: Berkeley DB Das Statistik-Feature sammelt Statistiken über verschiedene Bereiche des Programms, z.b. Speicherverbrauch, Transaktionen, Schreibzugriffe, Buffer Hit Ratio, usw. Die Auswahl des Statistik-Features erzwingt die Auswahl von 14 (von 37) weiteren Features, u. a. Transaktionen, Caches 22

23 Auflösung von Feature-Interaktionen

Klassifikation von Feature-Interaktionen Dynamisch vs. Statisch Dynamisch: Beim Ausführen einer Variante; unerwartetes Verhalten, Abstürze, Race Conditions Statisch: beim Generieren/Kompilieren einer Variante; z. B. Methode aufgerufen, die nicht definiert ist Domäne vs. Implementierung Domänenabhängigkeit: Die Abhängigkeit ist durch die Domäne konzeptionell festgelegt; alternative Implementierungen haben die gleichen Abhängigkeiten Implementierungsabhängigkeit: Abhängigkeit entsteht durch eine gewählte Implementierung; alternative Implementierung ist möglich 24

Dynamische Feature-Interaktionen Schwer zu erkennen Viel Forschung in Telekomunikationssystemen M. Calder, M. Kolberg, E.H. Magill, S. Reiff-Marganiec. Feature interaction: A critical review and considered forecast. Computer Networks, Volume 41, Issue 1, 2003, pp. 115-141 Bei Anforderungsanalyse durch spezielle Modellierung gezielt nach Interaktionen suchen Formale Spezifikation, Model Checking, Testen, testen, testen... Wenn gefunden Problem optionaler Features 25

Fokus: Implementierungsabhängigkeiten Implementierungsabhängigkeiten sind unangenehm Reduzierte Variabilität, obwohl Varianten in Domäne möglich wären Beispiel: Transaktionen vs. Statistiken (s.o.) Lösung 1: im Feature-Modell benötigt Statistik Transaktionen Reduzierte Variabilität Lösung 2: Keine Statistik über Transaktionen schlechtere Implementierung Daher gesucht: Möglichkeit Implementierungsabhängigkeiten aufzulösen 26

Lösungen für das Problem optionaler Features Wie modularisiert man zwei interagierende Features? Modul-Schnittstelle Ziele: Variabilität wie im Feature-Modell vorgesehen Geringer Implementierungsaufwand Effiziente Implementierung (Codegröße, Performance) Code Qualität (Trennung v. Belangen, Modularität) 27

Lösung 1: Mehrere Implementierungen Produkte Variability Impl. Effort Binary Size & Perf. Code Quality 28

Lösung 2: Abhängigkeit beibehalten (dokumentieren im Feature-Modell) Produkte Variability Impl. Effort Binary Size & Perf. Code Quality 29

Lösung 3: Quelltext verschieben (bis keine Abhängigkeit mehr vorhanden ist) Produkte Variability Impl. Effort Binary Size & Perf. Code Quality 30

Lösung 4: Verhalten ändern (orthogonale Implementierungen) Produkte Variability Impl. Effort Binary Size & Perf. Code Quality 31

Lösung 5: Präprozessor Produkte #ifdef TXN lock(); #ifdef STAT lockcount++; #endif #endif Variability Impl. Effort Binary Size & Perf. Code Quality 32

Lösung 6: Herauslösen der Interaktion (Derivatives) Produkte Variability Impl. Effort Binary Size & Perf. Code Quality 33

Lösungen im Überblick Qualität Größe & Performance Aufwand Variabilität Lösung Mehrere Implementierungen Abhängigkeiten beibehalten Quelltext verschieben Verhalten ändern Präprozessor Herauslösen der Interaktion Keine beste Lösung 34

Beispiel im Detail: Herauslösen der Interaktion Feature Modul enthält nur den eigenen Code, keinen Interaktionscode Neues Modul (A\B) wird immer (automatisch) ausgewählt wenn A und B ausgewählt sind A\B erweitert A oder B wenn beide ausgewählt Damit sind alle 4 Konfigurationen möglich ohne A, ohne B mit A, ohne B ohne A, mit B mit A, mit B (und mit A\B) Optimale Implementierung für alle Varianten 35

Probleme Manuelles Herauslösen sehr aufwendig Zusätzliche Module höhere Komplexität Interaktionen sind oft stark verteilte, heterogene Erweiterungen Theoretisch sehr viele Interaktionen möglich - maximale Anzahl paarweiser Interaktion bei n Features: i max = n 2 Auch Interaktionen zwischen mehr als zwei Features möglich = n 2 n 2 36

Interaktionen höherer Ordnung 37

Beispiel für Interaktion höherer Ordnung class Stack { boolean push(object o) { Lock lock=lock(); if (lock==null) { log("lock failed for: "+o) ; return false; remembervalue (); elementdata[size ++] = o;... void log(string msg) { /*...*/ boolean undo () { Lock lock=lock(); if (lock==null) { log("undo-lock failed") ; return false; restorevalue ();... log("undone.") ; 38

Wieviele Interaktionen? Theoretisch möglich (mit höherer Ordnung): h max n 1 = o= 1 o n 1 = 2 n n 1 Tatsächliche Anzahl Deutlich geringer Aber trotzdem häufig mehr als Features im System 39

46 Erfahrungen

Erfahrungen mit Berkeley DB Abhängigkeiten beibehalten? Wichtige Features waren de-facto obligatorisch (Statistiken, Transaktions, Speicherverwaltung, ) Verhalten ändern? Wir wollten das bestehende Verhalten beibehalten Herauslösen der Interaktion? 76% des Statistikcodes in 9 Module extrahiert möglich, aber aufwendig Präprozessor? Viel schneller, einfacher Deutlich verstreute und vermischte Belange 47

Erfahrungen mit FAME-DBMS Feature Modell ändern Vermeidet 14 Abh. und verhindert ¾ der Produkte API API get put delete Read Write Logging mit Präprozessor Vermeidet 11 Abh., aber verstreuter Quelltext B-Baum kann immer geschrieben werden Anstieg der Binärgöße um 5 13% 10 verbleibende Interaktionen herausgelöst 48

49 Diskussion: Variabilität in der Praxis

Welche Interaktionen auflösen? Variabilität ist kein Selbstzweck Mit 33 optionalen unabhängigen Features kann man eine Variante für jeden Menschen auf dem Planeten erstellen Mit 320 Features eine Variante für jedes Atom im Universum Niemand kann all diese Varianten testen; niemand braucht all diese Varianten Daher Konzentration auf benötigte Varianten Variabilitätsmanagement, Variabilität an der richtigen Stelle, Domänenanalyse 50

Exkurs: PKW-Produktlinien (BMW, Audi) 51

PKW-Produktlinien vor 20 Jahren Auswahl beschränkte sich auf Autotyp und ggf. noch wenige Extras wie alternativer Kassettenrekorder oder Dachgepäckträger Eine Variante (Audi 80, 1.3l, 55PS) machte 40% des Umsatzes aus 52

PKW-Produktlinien vor wenigen Jahren 1020 mögliche Varianten eines Audi; 1032 mögliche Varianten eines BMW Kaum ein Auto verlässt das Werk identisch zu einem vorherigen Allein 100 verschiedene Bodengruppen für ein Modell, je nach Motor und Ausstattung 50 verschiedene Lenkräder (3 vs. 4 Speichen, Holz vs. Kunststoff vs. Leder, Heizung, Farben) 53

Probleme der PKW-Produktlinien Hohe Variantenzahl verursacht enorme Kosten und Komplexität Hohe Logistikkosten Entwicklungsaufwand Investitionen für Werkzeuge und Anlagen Hohe Fertigungskosten aufgrund geringer Stückzahlen, besonders bei zugekauften Teilen Wir brauchen aber genügend Varianten, um die Kundenwünsche zu erfüllen. Lösungsansatz: Variantenmanagement als strategisches Projekt; beteiligt Entwickler, Logistiker und Marketing 54

Variantenmanagement bei PKW-Produktlinien Zuerst Analyse, was überhaupt und in welcher Kombination nachgefragt wird Exotische Varianten werden gestrichen Es sollte nicht sein, dass wir Teile entwickeln und herstellen, die wir dann nicht verbauen Variantenmanagement wird möglichst früh eingesetzt, schon bei der Entwicklung Audi konnte 5 Millionen Euro durch Variantenreduktion des Dachmoduls einsparen, indem das zentrale Bedienelement neutral gestaltet wurde, so dass es zu allen Dachhimmeln passt BMW hat die Anzahl der Bodengruppen von 100 auf 4 reduziert: Rechts-/Linkslenker, mit/ohne Schiebedach; für Kunden waren Unterschiede zuvor eh nicht sichtbar. 55

Variabilität in Softwareproduktlinien Nötige Variabilität bieten Unnötige Variabilität vermeiden Reduziert Entwicklungskosten Reduziert Testkosten Reduziert Wartungskosten z. B. Shorted Path von Weighted entkoppeln, wenn es Bedarf dafür gibt, sonst Abhängigkeit belassen z. B. Statistiken und Transaktionen nur mit Glue-Code trennen falls Bedarf erkennbar 56

Zusammenfassung Abhängigkeiten zwischen Features durch Feature- Interaktionen Implementierungsabhängigkeiten aufgelösen mit zusätzlichen Modulen Variantenmanagement sinnvoll 57

Ausblick Feature-Interaktionen sind ein offenes Forschungsfeld Interaktionen zwischen Features sind ein wichtiges Variabilitätsproblem in Produktlinien Dynamische Interaktionen sind sehr schwer zu erkennen Helfen Formalisierung und Werkzeugunterstützung? 58

Literatur I S. Apel, D. Batory, C. Kästner, and G. Saake. Feature- Oriented Software Product Lines - Concepts and Implementation. Springer, 2013. Kapitel 9: Feature Interactions J. Liu, D. Batory, and C. Lengauer. Feature Oriented Refactoring of Legacy Applications. In Proc. Int l Conf. on Software Engineering, 2006. [Auflösen von Interaktionen mit zusätzlichen Modulen] 59

Literatur II C. Kästner, S. Apel, S. S. ur Rahman, M. Rosenmüller, D. Batory, and G. Saake. On the Impact of the Optional Feature Problem: Analysis and Case Studies. In Proc. Int l Software Product Line Conference (SPLC), 2009. [Problem optionaler Features und unterschiedliche Lösungen] M.-S. Andres. Die Optimale Varianz. brand eins, 2006(1) [Varianten in der Automobilindustrie] 60

Softwareproduktlinien - Analyse von Produktlinien Christian Kästner (CMU) Sven Apel (Universität Passau) Gunter Saake, Thomas Thüm (Universität Magdeburg)

Das Problem

Variability = Complexity

33 optional, independent features a unique variant for every person on this planet

320 optional, independent features more variants than estimated atoms in the universe

Correctness?

Maintenance? Comprehension?

Checking Products 2000 Features 100 Printers 30 New Printers per Year Printer Firmware

Checking Products 10000 Features? Products Linux Kernel

Checking Product Line Implementation with 10000 Features #ifdef, Frameworks, FOP, AOP, Linux Kernel

Analyse von Feature-Modellen

Fragen an Feature-Modell und Konfigurationen Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. 13 Feature-Auswahl Generator Fertiges Program

Fragen an Feature-Modell Feature-Modell Ist das Modell konsistent? Welche Features muss man auswählen? Welche Features darf man nicht auswählen? Wie viele gültige Produkte gibt es? Sind zwei Feature-Modelle äquivalent?

Fragen an Feature-Modell und Konfigurationen Feature-Modell Feature-Auswahl Ist das Modell konsistent? Welche Features muss man auswählen? Welche Features darf man nicht auswählen? Wie viele gültige Produkte gibt es? Sind zwei Feature-Modelle äquivalent? Ist eine Feature-Auswahl gültig? Welche Features werden durch eine partielle Konfiguration bereits festgelegt?

Wiederholung: Feature-Modelle & Aussagenlogik Repräsentation von Feature-Modellen als Liste von Konfigurationen Aussagenlogischer Ausdruck Feature-Diagramm SPL OS ( Unix Win) ( Unix Win) ( Txn Write)

Wiederholung: Feature-Modell in Aussagenlogik übersetzen Wobei P für Parent und Ci für Child steht + Wurzel ist immer ausgewählt + alle Cross-Tree Constraints (Zusatzbedingungen) Alle diese Ausdrücke in Konjunktion verknüpfen

Analyse von Feature-Modellen Ist Feature-Auswahl gültig? {Root, Base, F1, F4 {Root, Base, F2, F3 Variablen in Formel ersetzen true wenn Feature in Auswahl, sonst false Formel ergibt true für gültige Auswahl

Ist das Feature-Modell konsistent? Gibt es mindestens eine Variante/Produkt? Formel erfüllbar? Anfrage an SAT-Solver SAT(FM)

Tote (Dead) Features Gegeben ein Feature-Modell Welche Features können ausgewählt werden? Welche Features müssen ausgewählt werden? Feature F auswählbar wenn SAT(FM F) Feature F abwählbar wenn SAT(FM F)

Partielle Konfigurationen Gegeben eine partielle Konfiguration Welche Features können noch ausgewählt werden? Welche Features müssen noch ausgewählt werden? Ausgewählte Features in Formel aufnehmen, dann wie tote Features Feature F noch auswählbar wenn SAT(FM AF F) Feature F noch abwählbar wenn SAT(FM AF F)

Änderungen von Feature-Modellen Welche Konsequenzen hat eine Änderung im Feature- Modell auf die Produktmenge? Refaktorisierungen, Spezialisierungen, Generalisierungen

Generalisierung von Feature-Modellen Informell (FM wird in FM verändert): Produkte aus FM bleiben erhalten, keine neuen Abhängigkeiten in FM Formal wenn Tautologie gilt: TAUT(FM => FM ) Also wenn: SAT( (FM => FM )) (Sonderbehandlung für hinzugefügte/entfernte Features sowie abstrakte Features nötig)

Generalisierung von Feature-Modellen

Spezialisierung von Feature-Modellen Informell: Keine neuen Produkte, Abhängigkeiten bleiben erhalten Formal wenn Tautologie gilt: TAUT(FM => FM) Also wenn: SAT( (FM => FM)) (Sonderbehandlung für hinzugefügte/entfernte Features sowie abstrakte Features nötig)

Spezialisierung von Feature-Modellen

Refaktorisierung von Feature-Modellen Informell: gleiche Produktmengen Informell: Spezialisierung + Generalisierung Formal wenn Tautologie gilt: TAUT(FM <=> FM ) Also wenn: SAT( (FM <=> FM )) (Sonderbehandlung für hinzugefügte/entfernte Features sowie abstrakte Features nötig)

Refaktorisierung von Feature-Modellen

Reasoning in FeatureIDE

Analyse der Implementierung

Fragen an die Implementierung Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. 31 Feature-Auswahl Generator Fertiges Program

Fragen an die Implementierung Kann ein Code-Block ausgewählt werden? Ändert eine Annotation etwas am Gesamt-Code? Wiederverwendbare Implementierungsartefakte

Annotationen bei Präprozessoren true WORLD BYE true

Berechnung von Presence Conditions line 1 #ifdef A line 2 #ifndef B line 3 #endif line 4 #elif defined(x) line 5 #else line 6 #endif true A A B A A X A X

Toter Quelltext (Dead Code) line 1 #ifdef A line 2 #ifndef A line 3 #endif line 4 #elif defined(x) line 5 #else line 6 #endif true A A A (= PC) A A X A X Kann nicht ausgewählt werden Analyse: SAT(PC)

Überflüssige (Superfluous) Annotation line 1 #ifdef A line 2 #ifdef A line 3 #endif line 4 #elif defined(x) line 5 #else line 6 #endif true A (= PC) A A (= PC ) A A X A X Immer gewählt wenn äußerer Block gewählt Analyse: SAT(PC PC )

Fragen an die Implementierung und das Feature-Modell Domain Eng. Feature-Modell Wiederverwendbare Implementierungsartefakte Application Eng. 37 Feature-Auswahl Generator Fertiges Program

Toter Quelltext (Dead Code) line 1 #ifdef A line 2 #ifdef B line 3 #endif line 4 #elif defined(x) line 5 #else line 6 #endif true A A B (=PC) A A X not A ^ not X Kann nicht ausgewählt werden Analyse: SAT(FM PC) Kombinierte Analyse von Feature-Modell und Implementierung

Überflüssige (Superfluous) Annotation line 1 #ifdef A line 2 #ifndef B line 3 #endif line 4 #elif defined(x) line 5 #else line 6 #endif true A (= PC) A B (= PC ) A A X A X Immer gewählt wenn äußerer Block gewählt Analyse: SAT(FM PC PC )

Analyse der Implementierung Fehler in Bezug auf das Feature-zu-Code-Mapping: Toter Quelltext (mit/ohne Feature-Modell) Überflüssige Annotationen (mit/ohne Feature-Modell) Feature verwendet, aber existiert nicht in Feature-Modell Feature aus Feature-Modell nicht verwendet Weitere wichtige Fehlerklasse: Typfehler Klasse/Methode/Feld wird Varianten aufgerufen, in denen sie/es nicht definiert ist Bei FOP: Methode enthält original, aber nicht in allen Varianten gibt es eine vorherige Rolle

Typsysteme für Produktlinien

Type Checking #include <stdio.h> char *msg = "Hello World"; int main() { printf(msg); Reference Type errors: referenced variable does not exist,

Variability-Aware Type Checking #include <stdio.h> #ifdef HELLO char *msg = "Hello World"; #endif #ifdef BYE char *msg = "Bye bye!"; #endif int main() { printf(msg);

Variability-Aware Type Checking #include <stdio.h> #ifdef HELLO char *msg = "Hello World"; #endif #ifdef BYE char *msg = "Bye bye!"; #endif int main() { printf(msg); Reference? Conflict?

Variability-Aware Type Checking Presence conditions: true HELLO BYE true #include <stdio.h> #ifdef HELLO char *msg = "Hello World"; #endif #ifdef BYE char *msg = "Bye bye!"; #endif int main() { printf(msg); Reference? Conflict?

Variability-Aware Type Checking true HELLO BYE TAUT(true -> true)? true #include <stdio.h> #ifdef HELLO char *msg = "Hello World"; #endif #ifdef BYE char *msg = "Bye bye!"; #endif int main() { printf(msg); Reference? TAUT(true -> (HELLO v BYE))? TAUT( (HELLO BYE))? Conflict?

Reachability: PC(Source) -> PC(Target) Conflicts: (PC(Def1) PC(Def2)) true HELLO BYE TAUT(true -> true)? true #include <stdio.h> #ifdef HELLO char *msg = "Hello World"; #endif #ifdef BYE char *msg = "Bye bye!"; #endif int main() { printf(msg); Reference? TAUT(true -> (HELLO v BYE))? TAUT( (HELLO BYE))? Conflict?

Einbeziehung des Feature-Modells true HELLO BYE #include <stdio.h> TAUT(FM -> (true -> true))? true #ifdef HELLO char *msg = "Hello World"; #endif #ifdef BYE char *msg = "Bye bye!"; #endif int main() { printf(msg); TAUT(FM -> (HELLO BYE))? Reference? TAUT(FM -> (true -> (HELLO v BYE)))? Conflict?

Einbeziehung des Feature-Modells true HELLO BYE #include <stdio.h> TAUT(FM -> (true -> true))? true #ifdef HELLO char *msg = "Hello World"; #endif #ifdef BYE char *msg = "Bye bye!"; #endif int main() { printf(msg); TAUT(FM -> (HELLO BYE))? Reference? TAUT(FM -> (true -> (HELLO v BYE)))? Conflict?

Einbeziehung des Feature-Modells true HELLO BYE #include <stdio.h> TAUT(FM -> (true -> true))? true #ifdef HELLO char *msg = "Hello World"; #endif #ifdef BYE char *msg = "Bye bye!"; #endif int main() { printf(msg); TAUT(FM -> (HELLO BYE))? Reference? TAUT(FM -> (true -> (HELLO v BYE)))? Conflict?

AST with Variability Information WORLD BYE 52 WORLD BYE Extended Reference lookup mechanism