Generative software product line development using variability-aware design patterns

Generative software product line development using variability-aware design patterns

Author’s Accepted Manuscript Generative Software Product Line Development using Variability-Aware Design Patterns Christoph Seidl, Sven Schuster, Ina ...

5MB Sizes 3 Downloads 105 Views

Author’s Accepted Manuscript Generative Software Product Line Development using Variability-Aware Design Patterns Christoph Seidl, Sven Schuster, Ina Schaefer

www.elsevier.com/locate/cl

PII: DOI: Reference:

S1477-8424(15)30060-9 http://dx.doi.org/10.1016/j.cl.2016.08.006 COMLAN233

To appear in: Computer Language Received date: 21 December 2015 Accepted date: 24 August 2016 Cite this article as: Christoph Seidl, Sven Schuster and Ina Schaefer, Generative Software Product Line Development using Variability-Aware Design Patterns, Computer Language, http://dx.doi.org/10.1016/j.cl.2016.08.006 This is a PDF file of an unedited manuscript that has been accepted for publication. As a service to our customers we are providing this early version of the manuscript. The manuscript will undergo copyediting, typesetting, and review of the resulting galley proof before it is published in its final citable form. Please note that during the production process errors may be discovered which could affect the content, and all legal disclaimers that apply to the journal pertain.

Generative Software Product Line Development using Variability-Aware Design Patterns Christoph Seidl, Sven Schuster, Ina Schaefer Technische Universit¨ at Braunschweig, Germany

Abstract Software Product Lines (SPLs) are an approach to reuse in-the-large that models a set of closely related software systems in terms of commonalities and variabilities. Design patterns are best practices for addressing recurring design problems in object-oriented source code. In the practice of implementing an SPL, instances of certain design patterns are employed to handle variability, which makes these “variability-aware design patterns” a best practice for SPL design. However, there currently is no dedicated method for proactively developing SPLs using design patterns suitable for realizing variable functionality. In this paper, we present a method to perform generative SPL development with design patterns. We use role models to capture design patterns and their relation to a variability model. We further allow mapping of individual design pattern roles to (parts of) implementation elements to be generated (e.g., classes, methods) and check the conformance of the realization with the specification of the pattern. We provide definitions for the variability-aware versions of the design patterns Observer, Strategy, Template Method and Composite. Furthermore, we support generation of realizations in Java, C++ and UML class diagrams utilizing annotative, compositional and transformational variability realization mechanisms. Hence, we support proactive development of SPLs using design patterns to apply best practices for the realization of variability. We realize our concepts within the Eclipse IDE and demonstrate them within a case study.

1. Introduction Design patterns are templates for standard solutions to recurring design problems, predominantly in object-oriented languages [1], e.g., Java, C++ or UML class diagrams (see Sec. 2.2). Software Product Lines (SPLs) are an approach to reuse in-the-large where a family of closely related software systems is represented in terms of commonalities and variabilities–often referred to as features (see Sec. 2.1). SPLs utilize, among others, object-oriented programming and modeling languages to realize features.

Email address: [email protected] (Christoph Seidl)

Preprint submitted to Journal of Computer Languages, Systems & Structures (COMLAN)September 12, 2016

Software Product Line

Design Pattern

In our previous work [2, 3], we analyzed multiple SPLs for their use of design patterns. We found that instances of the design patterns Observer [1], Strategy [1], Template Method [1] and Composite [1] are used to explicitly realize variability. Furthermore, we determined that there also are common practices with regard to how the different entities of a design pattern are distributed to individual features of a feature model in an SPL. As an example, Fig. 1 illustrates the Observer pattern, where an entity produces state changes (Observable/Subject) that are received by a loosely coupled interested entity (Observer/ConcreteObserver), e.g., to react to these state changes. Within the exemplary usage of Fig. 1 in an SPL context, the concrete entities of the pattern (i.e., ConcreteObserver, Subject) are realized by different features than the more general entities (i.e., Observer, Observable). The features of the figure are abstractions from a concrete SPL we inspected. *

F1

F2

F3

F4

F6

F5

F7

F8

Figure 1: Example of the Observer design pattern and a potential use of its entities by different features of an SPL.

Furthermore, we have determined that the distribution of a design pattern’s entities to features follows specific rules [4] (see Sec. 3) in order to realize functionality associated with particular features. With these findings, design patterns can be considered a best practice in SPL design so that it seems welladvised to explicitly employ them in developing SPLs. A design pattern is instantiated by implementing its entities in a particular language, e.g., Java or UML, even though the structure of the pattern does not have to be matched exactly to be valid (see Sec. 2.2). Furthermore, the instantiation of variabilityaware design patterns needs to incorporate the distribution of the individual entities of the design pattern to different features. Performing this procedure manually is both tedious and error-prone as the specification of the design pattern may inadvertently be violated by improper implementation. To aid the process of applying variability-aware design patterns to SPLs as best practices for design, we present a generative method that allows tailoring a pattern’s realization to a particular SPL and that generates realization artifacts that instantiate the pattern with specified parameters.

2

We provide definitions for the variability-aware versions of the design patterns Observer, Strategy, Template Method and Composite. Furthermore, we support generation of realizations in Java, C++ and UML class diagrams utilizing annotative, compositional and transformational variability realization mechanism (see Sec. 2.1). The rest of this paper is structured as follows: Sec. 2 provides foundations of SPLs, design patterns and role modeling. Sec. 3 elaborates on how to specify variability-aware design patterns as reusable catalog entries and provides catalog pages for the variability-aware versions of the design patterns Observer, Strategy, Template Method and Composite. Sec. 4 introduces our method of applying variability-aware design patterns to SPLs by generating required realization artifacts that contain appropriate variability information. Sec. 5 elaborates on the model-based implementation of our method. Sec. 6 discusses how our approach can be integrated in proactive, reactive and extractive SPL development processes. Sec. 7 demonstrates the feasibility of our method within a case study. Finally, Sec. 8 discusses related work before Sec. 9 closes with a conclusion and an outlook to future work. The work in this paper is mainly based on our previous work published in [5]. We improve over this work in the following points: For one, we define the variability-aware version of the Composite pattern and incorporate it into our generation facilities. Moreover, we provide detailed descriptions for each of the presented variability-aware design patterns in the form of a full catalog page. Furthermore, we extended our code generation facilities to also generate C++ code with appropriate preprocessor directives as annotative variability realization mechanism as is used frequently in industrial practice [6]. Accordingly, we extended our case study to incorporate the application of the Composite pattern and the generation of C++ code. In addition, we supply information on how to ease the application process of design patterns (see Sec. 4.3). Finally, we provide a detailed discussion on how to integrate our generative approach into SPL development processes for proactive, reactive and extractive development [7] (see Sec. 6). 2. Foundations The work presented in this paper generates artifacts of Software Product Lines (SPLs) by applying design patterns specified using role modeling. The following sections briefly introduce each of these constituents. 2.1. Software Product Lines (SPLs) Software Product Lines (SPLs) represent a family of closely related software systems in terms of common and variable functionality in order to foster large-scale reuse. In the conceptual problem space, a variability model governs configuration knowledge, e.g., in the form of a feature model [8, 9] (see Fig. 7), which represents configurable conceptual entities as features with a particular variation type: mandatory features are marked with filled circles and optional features are marked with hollow circles. Additionally, features may be assembled

3

in groups that further restrain configuration options: alternative groups allow selection of exactly one of the contained features and are marked with a hollow arc whereas or groups demand the selection of at least one feature and are marked with a filled arc. A configuration of a feature model is a selection of features that is valid with regard to the configuration knowledge. In the solution space, an SPL is implemented by various realization artifacts, such as source code or models. A variant derivation mechanism is employed to transform a conceptual configuration to a concrete variant or product of the SPL. Three principal types of variant derivation mechanisms may be distinguished [10, 11]: Annotative approaches assemble the variations of all possible configurations within a single artifact, e.g., as with the C++ preprocessor1 and the Java preprocessor Antenna2 . During variant derivation, the parts that are not needed within a variant are removed. Compositional approaches explicitly model the common core functionality of all configurations and, during variant derivation, add functionality required by individual features, e.g., as feature modules within Feature Oriented Programming (FOP) [12]. Transformational approaches designate a core variant that is changed through adding, modifying and removing elements to create a target variant that conforms with a particular configuration, e.g., as with delta modeling [13, 14]. 2.2. Design Patterns & Role Modeling Design patterns are best practices for solving recurring design problems in object-oriented source code and similar realization artifacts (e.g., UML class diagrams) [1]. A design pattern does not describe one concrete solution but provides guidelines on how to determine a specific design for a particular problem. For example, the Observer design pattern describes a solution for notification of state changes to loosely coupled interested parties. Its general structure as defined in [1] is presented in the upper part of Fig. 1. Catalogs of design patterns specify individual design patterns, among others, by their name, a description of the problem they address and a diagram of the different participating entities and their relations. The latter is usually presented in a form similar to UML class diagrams. Hence, design patterns are usually presented using a static design decision that describes one particular instantiation of the pattern. However, the same design pattern can manifest in different languages and in (slightly) different designs. Hence, a notation is required that captures the essence of a design pattern independently of the realization language and the exact structure of the implementation. The UMLlike notation used in [1] only satisfies the first point but seemingly suggests a fixed design. To remedy this problem, Riehle [15] suggests employing role modeling [16] as a means to represent design patterns. Role modeling describes dynamic object collaborations instead of a concrete design. Roles are defined as a language independent unit of collaboration. Their 1 https://gcc.gnu.org/onlinedocs/cpp 2 http://antenna.sourceforge.net/wtkpreprocess.php

4

a)

b)

c)

d)

e)

f)

0..*

Figure 2: Roles and relations as role modeling language elements. a) Use, b) Association, c) Prohibition, d) Implication, e) Equivalence, f) Requirement

potential interactions are specified by relations between them. Roles can be played by various different entities (e.g., source code elements) to instantiate a role model (see below). Fig. 2 represents roles and six relations, which are used as language elements for role modeling throughout the paper. We base our notation on that of [17], which defines the relations a) – e) as follows: The use relation describes that a role R1 employs role R2. The association expresses that a role R1 is in relation to role R2. The prohibition specifies that a role R1 and role R2 may never be played by the same entity. The implication defines that, whenever an entity plays a role R1, it also has to play R2. The equivalence relation expresses that two roles R1 and R2 always have to be played together. In Fig. 2 f), we add a further construct for the requirement relation to express dependence of a role R1 on a role R2 in the sense of a has-a relation for composition (see Sec. 3). *

Figure 3: Example of the Observer design pattern represented as role model.

Using these language elements, it is possible to describe design patterns using role modeling. For example, Fig. 3 shows the Observer design pattern represented as role model. To instantiate a role model for a particular design, its roles are mapped to entities of the implementing language (e.g., specific classes of Java), which satisfy the constraints of the role model (e.g., through their inheritance relations). For example, Fig. 4 shows one possible instantiation of the Observer design pattern for UML class diagrams. Even though the structure and names of the concrete design are not identical to those specified in the UML-like notation of the pattern (see Fig. 1), the instantiation of the design pattern is considered valid as it satisfies the constraints specified within the respective role model. We argue that role modeling is a suitable notation for capturing the characteristic structure of design patterns without inadvertently describing a definite design (in contrast to UML class diagrams) as the notation is independent of both the implementation language as well as the specific design to instantiate the pattern in a particular language. 3. Specification of Design Patterns As part of our previous work on analyzing SPLs [2, 3], we established that design patterns were not only used within individual features but also across 5

*

Figure 4: Example of instantiating the Observer design pattern for UML class diagrams by mapping roles of the pattern to elements of realization artifacts.

features to realize variability. For example, we found the Observer pattern decomposed over several features (see Fig. 1) where the loose coupling for information on state changes is used for communication over various features, e.g., with the general roles of the design pattern (Observer/Observable) implemented within one feature and the more specific roles (ConcreteObserver/Subject) being implemented within descendant features. To use design patterns in various languages, it is necessary to capture their essential characteristics. Existing catalogs list each design pattern with information such as its name, intent, structure, example usage and consequences of application. We use similar information as basis for the specification of variability-aware design patterns. For the general demand on the structure of the feature model, we utilize a role model with syntax similar to the one of the Observer pattern displayed in Fig. 3, which we refer to as Design Pattern Role Model (DPRM). DPRMs utilize the five language elements from Fig. 2 a) – e) with the following semantics: The use relation specifies that a role A is mapped to an entity, which uses the entity to which role B is mapped, e.g., by calling a method. The association describes that a role A is mapped to an entity, which is associated to an entity, to which role B is mapped, e.g., by holding a reference to that entity. The prohibition specifies that a role A and a role B may not be mapped to the same implementation entity. The implication expresses that an entity, to which role A is mapped, is related to an entity, to which role B is mapped, e.g., using inheritance. The equivalence relation defines that a role A and a role B have to be played by the same entity. To make a design pattern “variability-aware” for use within an SPL context, the rules and constraints that govern which roles of the design pattern are realized by which features have to be captured as part of the design pattern specification. The atomic units of decomposing a pattern’s elements to different features are the DPRM roles. However, the structure of the feature model representing the variable nature of a design pattern may take different concrete forms (see Fig. 7), e.g., as various different (partial) feature models may represent the same configuration logic. Hence, to support a generative procedure for instantiating design patterns within different SPLs (see Sec. 4), providing a concrete excerpt

6

of a feature model along with the design pattern does not suffice to describe all of the pattern’s potential distributions over features. To remedy this problem in the specification of a variability-aware design pattern, we devised Family Role Models (FRMs) [4] as a notation to capture constraints on the variable application of design patterns independent of the concrete structure of the specific feature model. FRMs are based on role modeling and, thus, utilize feature roles 3 and their relations to describe requirements on the configuration logic. An FRM is retrieved from a design pattern’s DPRM and knowledge of its possible use across features as determined by analyses of practical applications of the pattern within SPLs [4]. The constraints of the FRM specify in which way the feature roles may be mapped to individual features of a specific feature model. Fig. 5 a) shows an example of the FRM for the Observer pattern. a)

b) *

Figure 5: a) Example of the Family Role Model (FRM) for the Observer design pattern. b) Example of mapping the FRM of the Observer to the design pattern role model.

The DPRM and the FRM of a variability-aware design pattern represent a separation of concerns: The DPRM specifies constraints on the structure of the design pattern in possible realizations and the FRM defines constraints on the variable use within an SPL. To specify a variability-aware design pattern, the FRM is associated with the DPRM of the design pattern by mapping the feature roles to the design pattern roles, e.g., as in Fig. 5 b) for the Observer pattern. FRMs utilize the four language elements from Fig. 2 c) – f) with the following semantics: The prohibition specifies that a feature role A and a feature role B may not be mapped to the same feature. The implication expresses that a configuration that contains the feature mapped to feature role A always has to contain the feature mapped to feature role B. The equivalence relation defines that the feature role A and the feature role B have to be played by features that inevitably appear together in all possible configurations or by the same feature. Finally, the requirement relation states that the feature of feature role A depends on the feature played by feature role B (e.g., for implementation reasons) so that the feature of feature role B has to appear in all configurations that contain the feature of feature role A. The language elements a) and b) express semantics, which are only required by DPRMs, and are therefore not used by FRMs. From this definition of semantics of the individual language constructs for FRMs, it follows that similar constraints on the configuration logic may be expressed by multiple different yet similar FRMs. For the example in Fig. 5 3 In FOP, a feature role commonly refers to a contribution to a class through superimposition (e.g., adding a method) to realize a particular feature [18]. However, in the context of this paper, a feature role denotes an entity of the FRM that is to be associated with a feature.

7

a)

b) *

Figure 6: a) Example of an alternative Family Role Model (FRM) for the Observer design pattern. b) Example of mapping the alternative FRM of the Observer to the design pattern role model.

a), it would also be possible to specify a role model that merges the roles A and B as they are connected by a role equivalence similar to Fig. 6 a). Due to the mismatch in number of roles between the FRM and DPRM, the merged role would have to be employed multiple times in a mapping to the DPRM as illustrated by Fig. 6 b), which is, in principal, possible with both the concepts of role modeling and our realization. Even though this formulation would slightly change the configuration logic as the DPRM roles Observer and Observable would have to be played by exactly the same feature in each case, the FRM might be suitable as specification for possible application of the Observer pattern to feature models. However, as the distinction of DPRMs and FRMs stems solely from a separation of concerns for the individual elements of a design pattern, we feel that, in both these representations, every design pattern element should have an individual representation. Hence, the following assumes that, for every DPRM role there is a respective counterpart FRM role. An FRM may be satisfied by various different concrete feature models provided that the respective mapping fulfills the constraints of the FRM. For example, the FRM of the Observer design pattern from Fig. 5 a) may be realized by feature models such as the ones presented in Fig. 7. Even though these feature models are structured entirely differently and specify different configuration options, they are similar in the sense that they can be used to realize the variable nature of the Observer pattern so that its general parts are always present if the specific parts may be selected as part of a configuration. Hence, FRMs capture the essential variable nature of a design pattern independently of the feature model’s concrete structure of the SPL the pattern should be applied in. a)

b) F1

F2

F3

F5

F4

c)

F1

F1

F2

F2

F3

F3

F4

F5 > F3

F6

F5

(F2 < > F6) ˄ (F4 > F6 ˄ F5)

Figure 7: Examples for different feature models that satisfy the FRM of the Observer design pattern.

We have collected information on the design patterns Observer, Strategy, Template Method and Composite regarding their respective potential use within SPLs. 8

In the following sections, we describe these design patterns in the form of catalog entries similar to [1]. In addition, we explicitly capture information regarding the use of the variability-aware versions of these design patterns by employing both DPRMs and FRMs as well as guidelines for their potential usage within SPLs. However, we do not explicitly list information that is similar to usage of the design pattern in single systems, such as related patterns, as this is already defined in [1]. 3.1. The Observer Pattern Name: Observer Intent: Create an event notification of observing objects while modularizing concrete subjects and observers by functionality. Design Pattern Role Model (DPRM): *

Figure 8: The DPRM of the Observer pattern.

Fig. 8 depicts the DPRM of the Observer pattern. According to [1], the individual roles of the DPRM have the following characteristics: • Observer: defines an interface to perform an update upon state changes of a Subject • Observable: knows its Observers and provides methods to register and unregister Observers • ConcreteObserver: implements the update procedure defined by the Observer and maintains a reference to a Subject • Subject: notifies its Observers of any relevant state changes Family Role Model (FRM):

Figure 9: The FRM of the Observer pattern.

Fig. 9 depicts the FRM of the Observer pattern. The constraints on the configuration logic represent the following guidelines regarding variability-aware usage of the pattern: • Introduce general parts of the pattern described by Observer and Observable together in one feature, which results in an equivalence of the FRM roles A and B.

9

• Introduce Subject almost independently of the configuration knowledge. Only Observable has to exist, which results in a uses relationships from the FRM roles D to B. • Introduce ConcreteObserver in a feature that uses but is distinct from that of Observer and that of Subject, which results in a uses relationship and a role prohibition between the FRM roles C and A as well as and additional uses relationship and an additional role prohibition between the FRM roles C and D, respectively. Mapping FRM to DPRM: *

Figure 10: The mapping of the FRM to the DPRM of the Observer pattern.

Fig. 10 depicts the mapping of the FRM to the DPRM of the Observer pattern. Consequences: + The observer’s functionality is encapsulated independently of subjects. + Modularization of abstractions and concrete implementations is allowed, easing the extensibility for new Subjects and ConcreteObservers. - If both Subject and ConcreteObserver are introduced in optional features, implementation dependencies in terms of the feature-optionality problem [19] occur that must be considered during SPL development. A ConcreteObserver introduces an update operation, whose implementation depends on the particular Subjects as they might notify the ConcreteObservers about different kinds of data. Adding a Subject might lead to unexpected updates for ConcreteObservers. Hence, the update operation of the ConcreteObserver would have to be refined in order to understand the new updates. Example Usage: In a music player SPL, the Observer pattern may be used to notify different components, e.g., about a playback being started or stopped. If the playback is finished, a Playback feature might, e.g., notify a ProgressBar feature, such that the progress bar can be reset to its default state. 3.2. The Strategy Pattern Name: Strategy Intent: Encapsulate interchangeable algorithms/behavior in different features while providing a common interface in a more general feature. Design Pattern Role Model (DPRM): Fig. 11 depicts the DPRM of the Strategy pattern. According to [1], the individual roles of the DPRM have the following characteristics:

10

Figure 11: The DPRM of the Strategy pattern.

• Strategy: defines the common interface for the algorithms • ConcreteStrategy: realizes one variation of the algorithm by implementing the interface specified by Strategy • Client: is configured with a ConcreteStrategy and operates on the interface defined by Strategy Family Role Model (FRM):

Figure 12: The FRM of the Strategy pattern.

Fig. 12 depicts the FRM of the Strategy pattern. The constraints on the configuration logic represent the following guidelines regarding variability-aware usage of the pattern: • Introduce Strategy and Client together in one feature, which results in an equivalence of the FRM roles A and B. • Introduce ConcreteStrategy almost independently of the configuration knowledge. Only Strategy has to exist, which results in a uses relationship from the FRM role C to A. Mapping FRM to DPRM:

Figure 13: The mapping of the FRM to the DPRM of the Strategy pattern.

Fig. 13 depicts the mapping of the FRM to the DPRM of the Strategy pattern. Consequences: + Configure a Client at compile-time with varying behavior using one or more ConcreteStrategies. + Ease extensibility for new ConcreteStrategies. - Client must be made aware of existing ConcreteStrategies. To this end, the Template Method pattern might be suitable, filling an operation to register strategies with each feature that introduces a ConcreteStrategy. 11

Example Usage: For example, the Strategy pattern might be applied to realize hardware abstraction of interchangeable hardware. Reading values from different kinds of sensors, e.g., might require different concrete implementations to retrieve a sensor’s value. While the Sensor interface might be realized as a Strategy in a more abstract feature, the functionality specific to concrete sensors realized by the ConcreteStrategies might be encapsulated in different (alternative) features. 3.3. The Template Method Pattern Name: Template Method Intent: Encapsulate invariant parts of an algorithm in one feature, while factoring out varying parts to other features. Design Pattern Role Model (DPRM):

Figure 14: The DPRM of the Template Method pattern.

Fig. 14 depicts the DPRM of the Template Method pattern. Based on [1], the individual roles of the DPRM have the following characteristics: • Template: defines the general logic of an algorithm as sequence of calls to primitive operations • Hook: declares selected primitive operations defined in Template as being exchangeable parts of the algorithm • ConcreteHook: realizes the primitive operations of Hook to create one variation of the algorithm Family Role Model (FRM):

Figure 15: The FRM of the Template Method pattern.

Fig. 15 depicts the FRM of the Template Method pattern. The constraints on the configuration logic represent the following guidelines regarding variability-aware usage of the pattern: • Introduce Template and Hook together in one feature, which results in an equivalence of the FRM roles A and B. • Introduce ConcreteHook almost independently of the configuration knowledge. Only Template and Hook have to exist, which results in uses relationships from the FRM roles C to A and from the FRM roles C to B, respectively. 12

Mapping FRM to DPRM: Fig. 16 depicts the mapping of the FRM to the DPRM of the Template Method pattern.

Figure 16: The mapping of the FRM to the DPRM of the Template Method pattern.

Consequences: + Introducing general behavior in high-level features, letting low-level features implement domain-specific behavior, thus, concentrating on the essentials in low-level features. + Implementation similar to frameworks, exploiting inversion of control across features by letting subsequent features fill domain-specific parts of an algorithm. - Implicit implementation dependency: A feature introducing a ConcreteHook must provide implementations for the Hook methods. Example Usage: The Template Method pattern can be used in various applications where inversion of control is necessary. For example, a multi-language IDE developed as an SPL might make use of the Template Method pattern to call parsers or tool support for language editors that are provided by individual features. 3.4. The Composite Pattern Name: Composite Intent: Introduce a part-whole hierarchy encapsulating coherent functionality where specific parts of the hierarchy may be defined in individual features. Design Pattern Role Model (DPRM): *

Figure 17: The DPRM of the Composite pattern.

Fig. 17 depicts the DPRM of the Composite pattern. According to [1], the individual roles of the DPRM have the following characteristics: • Component: defines an interface used by elements in the composition represented by Composite and Leaf • Composite: defines behavior of complex elements and maintains a list of all children • Leaf: defines behavior of primitive elements without children

13

Figure 18: The FRM of the Composite pattern.

Family Role Model (FRM): Fig. 18 depicts the FRM of the Composite pattern. The constraints on the configuration logic represent the following guidelines regarding variability-aware usage of the pattern: • Introduce Component in an arbitrary feature. • Introduce Composite and Leaf almost independently of the configuration knowledge. Only Component has to exist, which results in uses relationships from the FRM roles B to A and from the FRM roles C to A, respectively. Mapping FRM to DPRM: *

Figure 19: The mapping of the FRM to the DPRM of the Composite pattern.

Fig. 19 depicts the mapping of the FRM to the DPRM of the Composite pattern. Consequences: + Clear encapsulation of coherent, tree-structured data and functionality. + Ease extensibility of tree elements. - Implicit implementation dependency: A feature introducing a Leaf must provide implementations for the Component methods. Example Usage: The Composite pattern might be applied when a variable tree structure is required where certain Leafs only exist in particular configurations. For example, a drawing tool for diagrams might use the Composite pattern to introduce composite figures. Primitive figure elements, e.g., different graphical notations for the same diagram, may be introduced in individual features. 4. Application of Design Patterns With the uniform and semi-formal specification of variability-aware design patterns presented in Sec. 3, it is possible to provide support for applying patterns in order to generate parts of an SPL’s realization artifacts (e.g., source code, design models). In the SPL context, design patterns may be used to implement functionality that is distributed over various features, e.g., an algorithm where the principle structure is defined in a base feature but where the specific parts

14

vary depending on the selection of a particular child feature. To create an implementation of a design pattern in a suitable notation, the elements of the design pattern have to be mapped to realization artifacts. To further incorporate the variability-aware nature of the design pattern, it has to be associated with the features of a feature model. In our method, the respective realization artifacts are generated to realize the design pattern but to also respect its variable nature. To ensure conformance of the realization of a design pattern with its respective specification, we perform validation on both the association with the feature model as well as with the generated realization artifacts. Fig. 20 presents an overview of the method. At point 1, the Family Role Model (FRM) is mapped to a feature model and the mapping is checked for validity. At point 2, the Design Pattern Role Model (DPRM) is mapped to elements of realization artifacts that are generated. The following sections elaborate on these constituent processes in detail. Software Product Line (Problem Space)

Design Pattern Specification

*

F1

F2

F3

Software Product Line (Solution Space)

F5

F4

F5 > F3

1

Design Pattern Role Model (DPRM)

Family Role Model (FRM)

2

Source Code (Java, C++ etc.) ...

*

Design Models (UML Class Diagrams)

Feature Model

FRM to DPRM Mapping

Realization Artifacts

Figure 20: Overview of the procedure to apply variability-aware design patterns within Software Product Lines (SPLs).

4.1. Family Role Model (FRM) and Feature Model Using the information from the FRM of a variability-aware design pattern’s specification, it is possible to establish the connection between the design pattern and the (already existing) feature model of the targeted SPL. For this purpose, each feature role of the FRM has to be associated with a specific feature. As domain knowledge is required to understand the meaning of individual features, creating the FRM mapping is a process that cannot be automated. Hence, FRM roles have to be assigned manually to suitable features to accommodate for the variable nature of the design pattern. For the mapping to be complete, each feature role of the FRM has to be assigned to a particular feature. However, it is possible that a single feature plays multiple roles at a time. Fig. 21 shows two tentative mappings of the FRM of the Observer design pattern to an exemplary feature model. 15

a)

b) F1

F2

F3

F1

F5

F2

F4

F3

F5 > F3

F5

F4

F5 > F3

Figure 21: Tentative mappings of the FRM of the Observer pattern to an exemplary feature model: a) invalid, b) valid.

Even in this synthetic example of limited size, it is not immediately obvious whether a particular mapping to a given feature model satisfies the rules of the FRM. With feature models from realistic SPLs, this problem is amplified. Yet, the correct mapping of the FRM to the feature model is essential for a proper instantiation of the variability-aware design pattern. Hence, we devised a procedure to detect and enforce valid FRM mappings. In the following, we explain this procedure and demonstrate it by showing that the mapping of Fig. 21 a) is invalid with regard to the rules of the FRM described in Fig. 5 a) whereas that of Fig. 21 b) is valid. A mapping of an FRM to a feature model is considered valid when three conditions are satisfied: a) all feature roles are assigned to a feature, b) all role prohibitions are respected by the mapped features and c) the configuration logic of the feature model and its cross-tree constraints guarantee that the constraints of the FRM are satisfied for all possible configurations. Condition a) is trivial to check on the mapping of the FRM to the feature model. Condition b) is also checked directly on the mapping by comparing the identity of the features mapped to the respective feature roles of the prohibition: If the features are distinct, the role prohibition is respected. However, condition c) is harder to check. Hence, we formulate a Boolean Satisfiability (SAT) [20] problem of the feature model, its cross-tree constraints and the FRM with its mapping to the feature model. To test a SAT problem, multiple conditions are phrased as propositional formulas over Boolean variables, and a SAT Solver attempts to find a valid assignment of truth values to all variables in order to demonstrate that the problem can be satisfied. In the following, we elaborate on the respective procedure within our method and illustrate it for the example of Fig. 21 by formulating and solving the SAT problem. In accordance with the literature [21, 22, 23], the configuration logic of a feature model is converted to SAT conditions by first creating a Boolean variable for each feature and then transforming the variation types and relations of features. This procedure consists of applying the following five rules: 1. The root feature R of a feature model is implicitly mandatory, which results in the SAT condition R ≡ true. 2. Selection of each child feature C demands selection of its parent feature P, which results in the SAT condition C → P. 16

3. Selection of a parent feature P demands selection of each mandatory child feature C, which results in the SAT condition P → C. 4. Selection of a parent feature P demands selection of at least one of the child features C1. . . Cn contained in an or group, which results in the SAT condition P → C1 ∨ . . . ∨ Cn. 5. Selection of a parent feature P demands selection of exactly one of the child features C1. . . Cn contained in an alternative group, which results in the SAT condition P → C1 ⊕ . . . ⊕ Cn (with ⊕ denoting the exclusive or). Furthermore, cross-tree constraints of the feature model given as propositional logic over features may directly be used as SAT conditions4 . The formulation of a feature model and its cross-tree constraints as SAT conditions is a procedure that is generally applicable for SPLs and is not specific to our approach. In Fig. 22, we illustrate the resulting SAT conditions for the feature model in the example of Fig. 21. F1

F2

F3

F1 F2 F1 F5 F3 F4 F2

F5

F4

F5 > F3

> F1 > F2 > F1 > F2 > F2 > F3

F4

F5 > F3

Figure 22: Example of formulating a feature model as SAT conditions.

Specific to our approach, the FRM and its mapping are formulated as SAT conditions as well. As described in Sec. 3, FRMs are formulated using merely the four role modeling language elements from Fig. 2 c) – d). Role prohibition is checked directly on the FRM mapping as specified above. The remaining three constructs are formulated as SAT conditions as follows: 1. A role implication between roles R1 and R2 is formulated as implication R1 → R2. 2. A role equivalence between roles R1 and R2 is formulated as equality R1 ≡ R2. 3. A requires relation 5 between roles R1 and R2 is formulated as implication R1 → R2. Fig. 23 illustrates the conversion of the FRM of the Observer Pattern from Fig. 5 a) to SAT conditions. 4 The alternative notation of cross-tree constraints as requires and excludes edges in the feature model may also be formulated as propositional logic as implication or exclusive or, respectively. 5 Despite similarly formulating role implication and requires relation as a logical implication, both syntactic elements are different on the level of FRMs due to their intended use: a role implication represents an is-a relation in the sense of subsumption, whereas a requires relation denotes a has-a relation in the sense of composition.

17

A≡B >A CC>D >B D-

Figure 23: Example of formulating the FRM of the Observer Pattern as SAT conditions.

To integrate these conditions into the SAT of the feature model, each reference to a feature role of the FRM is replaced with the respective associated feature of the FRM mapping. Fig. 24 shows the substitution of features for FRM feature roles assuming the FRM mapping of Fig. 21 a). F1

F2

F3

F1 F5 F5 F4

F5

F4

≡ F2 > F1 > F4 > F2

Figure 24: Example of substituting concrete features for feature roles using the FRM mapping of Fig. 21 a).

The resulting SAT conditions represent the rules of the FRM when using the specified FRM mapping, which must hold for all possible configurations. Rephrasing this condition, it is also possible to state that, in a valid mapping, it must not be possible to violate either one (or any combination) of these rules. To determine whether an FRM mapping may be violated and, thus, is invalid, we negate each individual SAT condition of the FRM rules and form a disjunction of the resulting constituents. For the example of Fig. 24, the resulting condition is ¬(F1 ≡ F2) ∨ ¬(F5 → F1) ∨ ¬(F5 → F4) ∨ ¬(F4 → F2). Using the resulting SAT condition along with those of the feature model creates a satisfiability problem to determine whether an FRM mapping is invalid. We negate the result of solving this problem to retrieve an answer to the question whether an FRM mapping is valid. For example, for the mapping of Fig. 21 a), a SAT solver would find a solution, such as the configuration {F1, F2, F3, F5}, which violates the requires relation between C and D so that the FRM mapping is considered invalid. Fig. 25 demonstrates the overall process of encoding an FRM and a tentative mapping to a feature model as SAT problem according to the above procedure. Encoding both the feature model with its cross-tree constraints as well as the FRM are independent of the tentative mapping. Merely the substitution of concrete features for the FRM roles and formulating a negated conjunction of the individual FRM rules are dependent on the mapping. This is beneficial when having to re-check altered mappings of the same pattern on the same feature model as significant parts of the encoding may be reused. It is worth noting that the part of the SAT problem that needs to be re-encoded for a different mapping does not require re-encoding the feature model or its cross-tree constraints so that the effort for encoding particularly large feature models is only required once independent of how many tentative mappings have to be checked. 18

Mapping-Dependent F1

A≡B >A CC>D >B D-

F2

FRM as SAT conditions F1

F2

F3

F5

F4

F5 > F3

F1 F2 F1 F5 F3 F4 F2

F3

> F1 > F2 > F1 > F2 > F2 > F3

F5

F4

F1 F5 F5 F4

≡ F2 > F1 > F4 > F2

FRM mapping as SAT conditions

¬(F1 ≡ F2) ˅ ¬(F5 > F1) ˅

F4

> F4) ˅ ¬(F4 > F2) ¬(F5 -

F5 > F3

Negate and form disjunction

Feature model as SAT conditions

Figure 25: Procedure to encode an FRM and its tentative mapping as SAT problem.

Due to these reasons, when creating the SAT for the FRM mapping in Fig. 21 b), the majority of the previously performed encoding may be reused. When using the FRM mapping of Fig. 21 b), the substitution of mapped features for the feature roles of the FRM is performed again and the following constraint for the FRM is created: ¬(F1 ≡ F2) ∨ ¬(F5 → F1) ∨ ¬(F5 → F3) ∨ ¬(F3 → F2). A SAT solver fails in finding a solution because the SAT problem is unsatisfiable, which, in turn, means that it is impossible to violate the rules of the FRM with any configuration. Hence, the mapping of Fig. 21 b) is considered valid. The described procedure to determine validity of a tentative FRM mapping implicitly assumes that no contradictions in the feature model exist, which would lead to an unsatisfiable SAT and, consequently, the false conclusion that the FRM mapping was valid. Hence, we check the satisfiability of the feature model on the respective SAT conditions before checking the validity of the FRM mapping. This procedure also has to be performed only once independent of how many tentative mappings have to be checked. 4.2. Design Pattern Role Model (DPRM) and Realization Artifacts To generate realization artifacts of a design pattern, it is further necessary to associate the roles of the DPRM of a variability-aware design pattern with the realization artifacts that should instantiate the pattern. Conceptually, the creation of the DPRM mapping differs depending on whether artifacts are created as part of an existing or completely new SPL: In the prior case, a part of the SPL is already present so that roles may be mapped to existing realization artifacts that are extended by generation, e.g., a DPRM role may be mapped to an existing Java class that is extended by

19

a generated method realizing part of a design pattern. In the latter case, realization artifacts instantiating a particular variability-aware design pattern are generated as part of the pattern instantiation process so that they do not exist as target of a mapping beforehand. Hence, for this case, it is not possible to create a mapping to elements of existing realization artifacts so that we use placeholder elements in the sense of a proxy [1] that contain enough information to instantiate a realization element in the generation process, e.g., if a Java class is to be generated, the package and class names are required. To generate an implementation for the design pattern, further general parameters are required depending on the target language of generation, e.g., the source folder for Java code or the model file for a UML class diagram. With these parameters for the realization artifacts and the mapping of the DPRM, it is possible to generate the implementation of a design pattern. We utilize model-based techniques for the generation by defining metamodels for the addressed target languages (see Sec. 5). Generating the realization artifacts means building instances of the respective metamodels and serializing them in an appropriate form6 , e.g., in the textual syntax of Java (see Sec. 5). Observer Strategy Template Method Composite ... Antenna Preprocessor FOP DeltaJ Comments ....

Composer

Java C++ UML ...

Figure 26: A composer is used to generate the implementation for a particular variability-aware design pattern in a specific target language with a selected variability realization mechanism.

The procedure for generating an instance of a variability-aware design pattern is specific to the target language as patterns may require different realizations in different languages, e.g., for Java, a single file per class is generated whereas, for C++, both a header and an implementation file are generated. Furthermore, the employed variability realization mechanism determines which artifacts are generated (e.g., Java code fragments for FOP but delta modules for DeltaJ, see Fig. 29). To abstract from these specifics as far as possible, we define a composer (see Sec. 5), which targets a selected variability-aware design pattern to generate the realization artifacts for a particular target language (e.g., Java, UML) using a specific variability realization mechanism (e.g., FOP, DeltaJ) as illustrated by Fig. 26. Composers may be created and contributed by developers external to our method for reasons of extensibility. The specifics of generating 6 This approach is beneficial in comparison to template-based textual approaches as it allows seamless integration of newly created and previously existing realization artifacts in reactive SPL development.

20

an implementation are encapsulated within the composer so that it is generally not possible to validate the inner workings of a composer. However, it is essential to validate that the created implementation conforms to the specification of the design pattern. Hence, we check the generated artifacts for conformance with the constraints defined for the structure of the pattern in the DPRM: The DPRM of the Observer pattern from Fig. 3 and its example mapping from Fig. 4 illustrate that the relations of the DPRM have to be maintained in the realization artifacts of the target language to consider an implementation a valid instantiation of the pattern. A valid mapping of the Observer pattern’s DPRM may similarly be employed to generate Java source code. Even though the implementations may not exactly replicate the structure and naming of the DPRM, they may realize the constraints of the DPRM by using the constructs of the target language, e.g., the inheritance mechanism represents the implication relation of the DPRM. Fig. 27 illustrates an example mapping of the DPRM roles of the Observer pattern to an implementation in Java source code where the target language’s constructs are used for a valid realization of the constraints imposed by the DPRM even though the concrete structure differs slightly. public interface Listener { public void update(T object); } public abstract class AbstractAudioController implements AudioController { protected List> playListeners; public void addPlayListener(Listener l) { this.playListeners.add(l); } protected void notifyPlayListeners() { for (Listener l : this.playListeners) { l.update(this); } } }

public class Mp3Controller extends AbstractAudioController { public void play() { // ... this.notifyPlayListeners(); } } public class PlayerBar { // ... class PlayListener implements Listener { public void update(AudioController a) { playButton.setEnabled(false); pauseButton.setEnabled(true); stopButton.setEnabled(true); } } }

Figure 27: Example of a valid mapping of the DPRM roles of the Observer pattern to parts of a realization in Java source code.

To validate the DPRM mapping to realization artifacts, unlike with the mapping of FRM roles, it is not possible to reduce the elements of the target language to conditions of a SAT problem. This is due to the fact that the relations between DPRM roles may be realized by different constructs of the target language, which could no longer be distinguished when reducing them to conditions of a SAT problem. Hence, for the validation of the DPRM mapping, the relations of the role model have to be lifted to the concepts of each realizing target language. For this purpose, we introduce language-specific validators for the DPRM mapping for each of the supported target languages (e.g., Java). A validator receives as input the generated artifacts in model-based form, the DPRM of the selected design pattern as well as the mapping from the DPRM to the generated realization artifacts. During validation, the validator assesses whether each of the relations specified in the DPRM is satisfied by the realization artifacts 21

assigned to the pattern roles via the DPRM mapping. For the equivalence and prohibition relation of the DPRM, by default, this check may be performed in a language-agnostic way by determining whether the respective realization elements of the roles have the same or a different identity, respectively. The procedure may be specialized for individual languages, e.g., equivalence might also be satisfied if the respective roles are mapped to two physically separated elements if they form a logically cohesive unit. In either case, the checks for the use, association and implication relations are language dependent. For example, for Java, the respective relations of the DPRM may be realized as follows: The use relation between roles R1 and R2 is realized if the class associated with R1 invokes the element associated with R2, e.g., if R2 is associated with a method, by performing a call of that method. The association between roles R1 and R2 is realized by a field of a class associated with R1 that references the class associated with R2. Depending on the multiplicity of the association, the field has to either be of a collection type (multiplicity 2–*) or the concrete type (multiplicity 0–1) associated with R2. Finally, an implication between roles R1 and R2 is realized by the inheritance relation of the class associated with R1 if the class/interface associated with R2 is extended/realized by the class associated with R1, respectively. Each of these relations may be satisfied transitively so that, e.g., the implication may be satisfied by multiple inheritance levels connecting the classes mapped to the respective DPRM roles. Even though there are similar concepts in the example target languages of Java, C++ and UML class diagrams, they are realized differently in the respective metamodels so that they cannot be checked in a uniform way. Furthermore, other languages may provide different means of realizing various relations, e.g., languages supporting mixins [24, 25] may also use this mechanism to realize the implication relation. Validators can be adapted to also accommodate for these language constructs in order to assure that the generated realization of a design pattern conforms to its essential structural specification in the DPRM even though the implementation may differ in details. 4.3. Assisting Pattern Application Although the design pattern generation process for different design patterns, target languages and variant derivation mechanisms is mostly automated, substantial manual effort is still required for mapping the DPRM to realization artifacts and for mapping the FRM to the feature model. In this section, we provide ideas on how this mapping process might be supported by automating parts of these mappings. Moreover, we provide ideas on how recommending design patterns for particular application scenarios might be possible in SPLs. When a legacy system is transformed to an SPL, design patterns might already exist within the realization artifacts. Hence, detecting such design pattern instances within the resulting SPL could automatically provide a mapping of the DPRM to the realization artifacts, which may be employed to identify a mapping of realization artifacts to features. To this end, the analysis infrastructure that we presented in previous work might be employed [3, 2, 4]. The analysis infrastructure is able to detect decomposed design pattern instances based on 22

the presented DPRMs while also determining which role of the DPRM is played by which realization artifact within the SPL. For example, if a decomposed Strategy pattern is detected where different ConcreteStrategies are introduced in individual features, a mapping between the ConcreteStrategy role and the realization artifacts can automatically be established. Provided that the affected parts of a realization artifact can be clearly attributed to a specific feature (e.g., when processing a feature module of FOP), the mapping of the FRM to the feature model can also be extracted. Moreover, developers could be assisted in the mapping process by offering suggestions on which DPRM role might be mapped to which realization artifact. To this end, assumptions on possible mappings may be applied when some steps of a particular mapping of the DPRM to realization artifacts have already been performed. For example, for the Strategy pattern, it is common that the ConcreteStrategy role is played by a direct sub-class of the class playing the Strategy role. If the Strategy role is mapped to a particular pre-existing class and if this class already has pre-existing subclasses, these subclasses could be suggested as possible mappings for the ConcreteStrategy role. This way, developers would be assisted in creating a suitable mapping of DPRM roles to realization artifacts. In addition, it might be possible to assist developers during the selection of variability-aware design patterns. There exists a body of research on design pattern recommendation systems in single software systems [26, 27, 28, 29]. Most of these recommendation systems work on a design pattern database that is queried for a specific intent of the developer, e.g., by asking specific questions to the developer [27, 28] or using natural language processing to filter the intent from a textual scenario description [29]. Such techniques might be adapted for SPLs by extending the design pattern database with variability information on each pattern (i.e., storing variability-aware design patterns). Moreover, the queries must be refined by also determining the variability developers intend to realize, e.g., by a questionnaire. Other approaches analyze the existing design to detect possibilities for design pattern application in order to recommend suitable design patterns for particular scenarios [26]. Such approaches might be extended by incorporating variability information during the design analysis. For example, if an algorithm with similar functionality but different non-functional qualities is realized in individual features, the variability-aware Strategy pattern might be suggested. Using such a suggestion mechanism for variability-aware design patterns, the mapping of the FRM to the feature model might be assisted. When considering the proposed Strategy pattern for similar algorithms in individual features, suggestions for possible mappings similar to the previously mentioned suggestions of DPRM mappings to realization artifacts could be made similar to the example presented above. 5. Implementation We implemented the method to generate variability-aware design pattern instantiations as presented in this paper within the Eclipse IDE. Throughout 23

the implementation, we utilize the Ecore metamodeling notation from the Eclipse Modeling Framework (EMF): We created a textual Domain-Specific Language (DSL) using Xtext7 of the EMF to specify patterns with their respective details according to Sec. 3. Fig. 28 shows an example of the DSL used to specify the Observer pattern.

Figure 28: Example of the Domain-Specific Language to specify variability-aware design patterns.

We added three further metamodels for DPRMs, FRMs and their mappings, whose instances may, e.g., be created using a graphical notation similar to Fig. 3 and Fig. 5. We created an Eclipse extension point to register variability-aware design patterns with our system, which provides for loose coupling and extensibility. We created a further Eclipse extension point to register composers with our system, which instantiate variability-aware design patterns so that additional languages and variability realization mechanisms may be incorporated into the generation process. To support application of a variability-aware design pattern within an SPL, we provide guidance to developers. The description of a design pattern’s intent, addressed problem, application context and its specific focus on variability may be utilized in selecting a suitable design pattern to realize variable functionality. We currently supply specifications of the variability-aware Observer, Strategy, Template Method and Composite patterns in accordance with the findings in our previous work [4, 2, 3]. 7 https://eclipse.org/Xtext

24

As part of preparing the generation process, we further support creating the mapping of the FRM to the feature model of the SPL. We implemented the procedure of formulating the mapping as SAT from Sec. 4.1 to provide user guidance by excluding features that are invalid as targets for the mapping of an FRM role as well as to enforce validity of the created mapping. In addition, it is possible to define the mapping of DPRM roles to elements of realization artifacts. When instantiating a design pattern for an already existing SPL, this means that the roles are mapped to already existing elements. When instantiating a design pattern for a new SPL, this means that parameters, such as package and class names, are provided for the respective elements of the realization artifacts that are subsequently generated. In addition, parameters may be required that are specific to creating artifacts of a particular target language, e.g., which folder a generated UML class diagram should be placed in. We support user input of values for such elements by allowing each composer to add arbitrary additional elements to the user interface when guiding developers in creating an instantiation of a variability-aware design pattern. Furthermore, an appropriate composer may be chosen that instantiates the variability-aware design pattern for the intended target language with the desired variability realization mechanism. As a proof of concept for different languages used in the generation process, we currently support the textual languages Java and C++ as well as graphical UML class diagrams, which we equally perceive as models (see below). To support variability-aware application of a design pattern within the realization artifacts of an SPL, we support the following variability realization mechanisms: For Java, we support the Antenna preprocessor (annotative), FOP (compositional) and DeltaJ (transformational). For C++, we support preprocessor directives (annotative) and FOP (compositional). For UML class diagrams, we support annotation of variable parts with feature expressions through comments (annotative) and delta modeling through DeltaEcore [30] (transformational). a)

b)

public class Mp3Controller extends AbstractAudioController { // #ifdef MP3 public void play() { // ... this.notifyPlayListeners(); } // #endif }

Annotated Java (MP3Controller.java)

c)

public class Mp3Controller extends AbstractAudioController { public void play() { // ... this.notifyPlayListeners(); } }

Feature Module (MP3Controller.java)

delta MP3 { adds { // ... public class Mp3Controller extends AbstractAudioController { public void play() { // ... this.notifyPlayListeners(); } } } }

Delta Module (MP3.deltaj)

Figure 29: Examples of Java artifacts generated for different variability realization mechanisms when mapping FRM role D to a feature MP3: a) annotative with Java code that contains Antenna preprocessor comments, b) compositional with a FOP feature module, c) transformational with a DeltaJ 1.5 delta module.

25

For the model-based generation, we use the Java Model Printer and Parser (JaMoPP)8 to perceive Java code as EMF-based model as well as the EMF metamodel for UML provided by Eclipse9 . For C++, we use a template-based generation process. We further incorporate the notion of variability into the generation process by evaluating the FRM mapping and using its information for the realization artifacts. Depending on the variability realization mechanism of the chosen composer, the content or even the type of generated artifact may differ: With Antenna preprocessor annotations in Java, variability information is encoded into comments so that regular Java code may be generated. With FOP, feature modules with Java code are created that are syntactically valid but may not be valid with regard to static semantics when inspected in isolation, e.g., when a variable is referenced that is defined in another feature module. Finally, with DeltaJ, delta modules are created that contain transformation instructions in a domain-specific language that closely resembles Java but differs in syntax. Fig. 29 illustrates each of these cases with an example. Annotative

Compositional

Transformational

Observer

Java (Antenna), C++ (Preprocessor), UML Class Diagrams (Comments)

Java (FOP), C++ (FOP)

Java (DeltaJ), UML Class Diagrams (DeltaEcore)

Template Method

Java (Antenna), C++ (Preprocessor), UML Class Diagrams (Comments)

Java (FOP), C++ (FOP)

Java (DeltaJ), UML Class Diagrams (DeltaEcore)

Strategy

Java (Antenna), C++ (Preprocessor), UML Class Diagrams (Comments)

Java (FOP), C++ (FOP)

Java (DeltaJ), UML Class Diagrams (DeltaEcore)

Composite

Java (Antenna), C++ (Preprocessor), UML Class Diagrams (Comments)

Java (FOP), C++ (FOP)

Java (DeltaJ), UML Class Diagrams (DeltaEcore)

Table 1: Overview of the combinations of variability-aware design pattern, variability realization mechanism and target language currently supported by the provided implementation.

We support each of the illustrated cases by supplying composers for the variability-aware design patterns Observer, Strategy, Template Method and Composite with the target languages Java, C++ and UML class diagrams using the variability realization mechanism Antenna, preprocessor directives, FOP, annotations through comments, DeltaJ and DeltaEcore. Table 1 shows a detailed overview of the supported combinations of variability-aware design pattern, variability realization mechanism and target language. With this contribution, it is possible to generate the instantiation of variability-aware design patterns as best-practices for the creation of variable functionality within SPLs. Our generative method improves over a manual procedure in that it ensures that the realization of the design pattern and its variable nature are in accordance with 8 http://www.jamopp.org 9 https://wiki.eclipse.org/MDT/UML2

26

its specification while still allowing flexibility in creating implementations that slightly diverge from the default naming and structure of a design pattern. 6. Integration into Software Product Line Development Processes In SPL engineering, three principal types of SPL development may be distinguished: proactive, reactive and extractive development [7]. In the following, we elaborate on each of these types of development and discuss the relevance of our approach for each one of them. 6.1. Proactive Development In proactive development, an SPL is newly developed without any previous system. This means, that the conceptual elements of the problem space as well as the realization elements of the solution space of the SPL are created anew. Hence, the feature model as well as all elements including variability information (e.g., feature modules) have to be developed as part of this process. In our approach, we assume that the feature model is developed manually to capture the central abstractions of the domain in appropriate features. Existing approaches for extracting feature models rely on realization artifacts of an SPL to be available [31, 32], which is not the case in our approach before generating the respective pattern instance. Generating (parts of) the feature model as part of pattern instantiation poses a significant challenge as domain knowledge is required to determine a suitable granularity level for features. However, the knowledge on the specific pattern being instantiated as well as its individual roles as specified in the DPRM and FRM may potentially aid the process of synthesizing adequate features for (parts of) a variability-aware design pattern: For one, the roles of the DPRM present the central abstractions of a design pattern, which may be utilized to, e.g., suggest names for features if the feature is related to a single DPRM role (as determined via the FRM to DPRM mapping and the FRM to feature model mapping). Furthermore, the constraints on configuration options imposed by a pattern’s FRM may be used to create respective relations in the feature model, e.g., a role implication in the FRM may indicate a parent-child relation in the feature model. We intend to explore the potential of techniques to also generate parts of feature models within our future work. However, the focus of our current work is the instantiation of a variabilityaware design pattern in terms of its realization artifacts with their relation to the feature model. For this purpose, we present multiple composers to generate realization artifacts containing variability for the target languages Java, C++ and UML class diagrams (see Sec. 5) as well as various annotative, compositional and transformational variability realization mechanisms. All of these composers may be used within proactive SPL development to generate instances of the presented variability-aware design patterns. In addition, we designed the mechanism to incorporate composers explicitly to be extensible so that new target languages, variability realization mechanisms or variability-aware design patterns may be supported by registering the respective generation procedures. For proactive

27

development, both a model-based and a template-based generation procedure for the realization artifacts of a variability-aware design pattern are suitable. 6.2. Reactive Development In reactive development, an existing system is extended with variabilities as configuration options. Hence, both the conceptual elements of the problem space as well as the realization elements of the solution space of an SPL may, in part, be already present when instantiating variability-aware design patterns. In our approach, we account for both an existing feature model as well as, principally, for partially existing realization artifacts that contain variability. For feature models, we again assume that newly necessary features are created outside of our approach so that all features relevant to the instantiation of the variability-aware design pattern are present before the generation procedure. Hence, it is possible to perform and check the mapping of FRM roles to features with the procedures of this paper. In addition, as parts of the realization artifacts of the SPL already exist, the mapping of DPRM roles to realization artifacts with reactive development is conceptually easier than with proactive development: In proactive development, none of the realization artifacts of the design pattern exist before the generation procedure so that a mapping has to be performed to placeholder elements that capture all essential data in the sense of a proxy (see Sec. 4.2), which creates additional complexity. In contrast, in reactive development, parts of the realization artifacts of the design pattern exist before the generation procedure so that they may serve as targets of the mapping directly. However, the complexity of the generation of artifacts is opposite to that for mapping roles: In proactive development, all elements of a variability-aware design pattern may be generated anew with no regard to already existing structures, names etc. In contrast, in reactive development, existing elements have to be incorporated into the generation process. On a conceptual level, this means, among others, that names of elements may not necessarily be chosen freely and that existing class hierarchies have to be respected. On a practical level, this entails that artifacts of a particular target language and variability realization mechanism need not only be written (as part of generation) but also read (as part of analysis of existing structures). As template-based generation procedures are solely concerned with writing artifacts, they may not be used for reactive development without adding facilities to read existing artifacts. On the other hand, model-based techniques form a suitable basis for writing and reading artifacts: While a model-based generation technique also only addresses the writing of artifacts, the existence of a suitable metamodel for the target language and the variability realization mechanism require relatively low effort to also support reading of artifacts. For textual languages, tools such as Xtext may be supplied with a grammar to generate a parser that yields model representations of, e.g., source code. For graphical notations with an appropriate metamodel, usually, the editor either saves model representations directly or allows the export to a format that may be transformed to a model representation.

28

In the implementation of our approach, we heavily capitalize on the benefits of model-based generation. As a consequence, we also support reactive development for the majority of the presented target languages and variability realization mechanisms, namely Java and UML class diagrams with all presented variability realization mechanism. Merely for C++, we rely on a template-based generation procedure so that we do not support reactive development. This problem may principally be remedied by providing a suitable grammar for C++ to a tool such as Xtext to read textual source code. However, due to the complexity of the syntax of the C++ language, there is a significant adoption barrier if striving for support of the complete language. As part of our ongoing development efforts, we will inspect whether it is feasible to support a well-defined subset of the C++ syntax that can be parsed more easily in order to support reactive development of real-world SPLs based on C++. 6.3. Extractive Development In extractive development, an SPL as a managed approach to variability is introduced to a group of systems that were not variability-aware. As part of this process, information regarding variability is extracted from multiple individual systems that either were developed in isolation or created by clone-and-own (copying and modifying). From the results of these analyses, a feature model may be synthesized and variability-aware realization artifacts may be generated semi-automatically. At the current stage of development, our approach does not support extractive development. However, we presume that the use of variability-aware design patterns potentially bears significant benefits for extractive development: As design patterns are accepted as a best practice in object-oriented design [1], we assume variability-aware design patterns to be a best practice in SPL design as they are commonly used to realize variability as determined in our previous work [2, 3]. Hence, when restructuring legacy code that is not variability-aware to an SPL, it may also be worth transforming the implementation to incorporate variability-aware design patterns. For this purpose, it would be sensible to extend our previous work on variability mining [33, 34, 35], which already utilizes modelbased technology, and to supply refactoring [36] operations that yield variabilityaware design patterns. In that sense, the violation of a pattern would be considered as a bad smell [36], which is eliminated by an appropriate refactoring operation that created the respective variability-aware design pattern. Besides creating the refactoring operations for transformation, a significant challenge in this approach is the detection of violations of variability-aware design patterns. For this purpose, we will explore the possibility to adapt our model-based technologies for detecting design patterns [2] to also detect deviations form those design patterns. The model-based representation of realization artifacts and their variability realization mechanism utilized heavily throughout our implementation further forms a very suitable basis for the implementation of refactoring

29

operations as tools such as Refactory10 are designed explicitly to support easy refactoring of models. Furthermore, previous work on refactoring SPLs by colleagues from our group [37, 38] make the target language Java with the variability realization mechanisms FOP and DeltaJ prime candidates for a tentative realization of support for extractive development as part of our future work. 7. Case Study To demonstrate the feasibility of our method, we performed a case study utilizing the presented generation procedure: In our previous work [4], we analyzed 8 FOP-based SPLs, realized in Java, for the usage of variability-aware design patterns. We found multiple instances of design patterns that were distributed across various features. Within the case study of this paper, we use our generative method to re-create instantiations of the respective design patterns that are similar to the ones we detected previously. SPL

SLOC

Features

FeatureAMP

2,497

29

Patterns Observer

GameOfLife

1,466

21

Observer, Stragety

Violet

7,470

88

Composite, Template Method

Table 2: Overview of the SPLs used for the case study [4].

We performed the case study as follows. We extracted the design pattern instances from the FOP-based SPLs FeatureAMP 11 , GameOfLife 12 and Violet 13 , which contain instances of the variability-aware design patterns specified in this paper [4]. In Table 2, we provide additional data on the analyzed SPLs in terms of source lines of code, number of features and the design patterns detected in the respective SPL. Using our implementation, we re-created these design pattern instances by generating or extending respective realization artifacts in Java using FOP as variability realization mechanism. For example, for the Observer pattern in FeatureAMP, we mapped the respective realization artifacts to their implementing features as illustrated in Fig. 30. To create multiple different instances of the ConcreteObserver and Subject, we applied the pattern generation multiple times. First, we proactively created the realization artifacts for the pattern abstractions (i.e., Observer, Observable) including one instance of each Subject and ConcreteObserver. Afterwards, we reactively generated other instances for the Subject or ConcreteObserver by mapping the roles for the abstractions to their, now existing, realization artifacts. Furthermore, we improved over the existing SPL realization in FOP by further utilizing other variability 10 http://modelrefactoring.org 11 http://spl2go.cs.ovgu.de 12 http://fosd.net/fuji 13 http://violet.sourceforge.net

(refactored legacy system)

30

realization mechanisms to incorporate variability in Java, namely the Antenna preprocessor and DeltaJ. Besides Java code, we also generated C++ code utilizing both preprocessor directives and FOP as variability realization mechanism. In addition to generating source code for variability-aware design patterns, our implementation is also capable of generating an analogous instantiation of a variability-aware design pattern as UML class diagrams utilizing comments and a delta language specified in DeltaEcore as variability realization mechanism. BaseFeatureAmp

PlayerBar

x3

FileSupport

MP3

PlayList

OGG

PlayerControl

QueueTrack

Figure 30: Feature model and mapping of the FRM of the Observer pattern for the FeatureAMP SPL of the case study.

We found that our approach and corresponding implementation are capable of re-creating equivalent design pattern instances for the pattern instances detected in our previous work. Moreover, only valid pattern instances in accordance to the DPRM and FRM could be created. However, manual adaptation and integration were necessary to create an implementation that is identical to that of the original SPL. For example, for the Observer pattern in FeatureAMP, this included, among others, introducing generics to the Observer interface or registering ConcreteObservers at the corresponding Subjects. We could perform these adaptations using tools provided by the Eclipse IDE, such as semantics preserving refactorings. Interpreting these results, our approach is feasible and facilitates applying variability-aware design patterns as best practice in creating SPLs. However, advanced tool support that allows more interaction with developers could further reduce effort. For example, the generation of multiple realization artifacts for one role of the DPRM, e.g., for multiple ConcreteObservers, could be facilitated by allowing description of cardinalities for roles in the DPRM and adapting the mapping process accordingly. Moreover, necessary adaptations to the generated pattern instance that can be performed using refactorings could also be implemented in more advanced composers. Yet, we showed that the method of this paper may be employed to generate instances of design patterns as they are used in practice by manual implementation. A threat to validity of the case study is the uncertainty regarding whether the design patterns we extracted from FOP code may equally be used as best practices within other variability realization mechanisms. However, the results of our generative method with other variability realization mechanisms, such as DeltaJ, suggest that the design patterns may be used analogously. Moreover, we only inspected Java code for extracting variability-aware design patterns [4]. Programming languages offering advanced language constructs such as, e.g., Scala or Ruby, may present different incarnations of variability-aware

31

design patterns, which may require an adaptation of the generation procedure. However, we showed the principle procedure of adapting our method to other target languages of similar and different structure by also supporting C++ and UML class diagrams in the generation process. In conclusion, automatically generating instances of variability-aware design patterns for different languages and various variability realization mechanisms using our method based on DPRMs and FRMs is feasible and, conceivably, reduces effort as well as proneness to errors when compared to a manual procedure. 8. Related Work Design patterns as an abstract design concept have been introduced by Gamma et al. [1] and since then there has been exhaustive research on design patterns as well as regular additions of new patterns [39, 40, 41, 42, 43]. For example, Zimmer [39] investigated the relationships between the design patterns proposed by Gamma et al. [1]. Gamma [40] and B¨ aumer et al. [43], proposed new design patterns solving more complex challenges in object-oriented design. Beck et al. [42] described the real-world experience of using design patterns in an industrial context. Moreover, the notion of patterns has also been lifted to a more abstract level of describing architecture patterns [41]. However, besides our work, there has only been little research on design patterns in the context of variability or SPLs. Existing research on design in SPLs includes Apel and Beyer [44] investigating cohesion and coupling between features in feature-oriented SPLs and K¨ astner et al. [45] discussing benefits and costs of feature interfaces. We contribute to this research by providing a generative approach to proactively and reactively apply design patterns as best practices for SPL development. Hannemann and Kiczales [46] modularize design patterns in the context of AspectJ [47], an extension to Java allowing Aspect-Oriented Programming (AOP) [48], which can also be used for SPL development. They propose AspectJ implementations of the design patterns documented by Gamma et al. [1] pointing out potential benefits compared to standard pattern implementations. However, unlike with our approach, they do not inspect the variability-aware usage of the patterns or generate pattern implementations. Riehle [15, 49] also describes design patterns using role modeling as languageindependent notation. However, the work neither inspects nor documents the usage of these patterns within an SPL context. Furthermore, Reimann et al. [50] present generic model refactorings where they use role modeling to specify the principle structure of an implementation similar to how we do for design patterns. However, unlike with our approach, they do not generate an implementation from the role model but use it to perform semantics preserving transformations to similarly structured implementations, which supports various languages. Their work may be complementary to our future work in supporting extractive SPL development when using their refactorings to restructure a legacy code base to an SPL by utilizing variability-aware patterns. Multiple authors recognized the benefits of employing design patterns by generating source code for them or by restructuring existing code to utilize 32

design patterns [51, 52, 53, 54]. Albin-Amiot et al. [55] propose a metamodel to describe design patterns, which is used for both design pattern detection and code synthesis. However, neither of these approaches supports the use of variability-aware design patterns in an SPL context. Yet, our method aligns with their general practice of providing user guidance in applying an appropriate design pattern and ensuring its adequate realization. Dabholkar and Gokhale [56] employ AOP and FOP to specialize generalpurpose middleware by customizing existing design pattern implementations with concrete functionality. In contrast, our approach generalizes the description and generation of variability-aware design patterns for SPL development. In further work [57], Dabholkar and Gokhale apply model-based techniques to map requirements of conceptual features from specific SPL variants to realizing features of a middleware. For this purpose, they employ featureoriented reverse engineering utilizing design patterns, which is the opposite direction to our generative procedure. As selecting the correct pattern for a particular scenario is not straightforward, multiple authors investigated recommendation systems for design patterns [28, 29, 26, 27]. All of these approaches have in common that they provide a database with unified information about design patterns. Kung et al. [28] and Palma et al. [27] store conditions for each design pattern that describe when the pattern might be applied. These conditions are transformed into questions on different abstraction layers, which the developer has to answer in order to get a pattern recommendation for a particular scenario. Suresh et al. [29] query the database by applying natural language processing on a textual scenario description in order to determine the intent of the developer and recommend a pattern accordingly. Bouassida et al. [26] perform semantic analyses on existing design based on element names and their relations in order to recommend suitable design patterns that should improve the current design. 9. Conclusion In this paper, we presented a method to specify and apply variability-aware design patterns as best practices for SPL design within a generative procedure to create suitable implementations of a pattern. We specified variability-aware patterns with their respective data (name, intent etc.) as well as role models for the design pattern (DPRM) as well as constraints on its variable nature within an SPL (FRM). Using this schema, we provided catalog entries for the variability-aware versions of the design patterns Observer, Strategy, Template Method and Composite. Within the generation procedure, the FRM of a variability-aware design pattern is associated with a particular feature model of an SPL to tie a design pattern to an SPL. We showed how to utilize the specified FRM to validate and enforce validity of the mapping using a SAT solver. Furthermore, the DPRM is associated with the realization artifacts that are to be generated for the design pattern, and the validity of the generated artifacts is validated with regard to the specification within the DPRM. In addition to the strictly generative procedure for proactive SPL development, 33

we also support reactive SPL development where only parts of the implementation are generated within an already existing infrastructure. We implemented this procedure on basis of EMF for use within the Eclipse IDE to generate implementations of the supported variability-aware design patterns in Java, C++ and UML class diagrams utilizing annotative (preprocessor, Antenna, comments), compositional (FOP) and transformational (DeltaJ, DeltaEcore) variability realization mechanisms. Finally, we demonstrated the feasibility of our approach within a case study re-creating the realization of variability-aware design patterns we found used in practice as part of our previous work [4]. Our approach principally supports the generation of instances of variability-aware design patterns in proactive and reactive SPL development. In our future work, we will further explore how to reduce specification effort for design patterns to increase the benefits of our approach. For this purpose, we will explore how to recommend particularly useful patterns for realizing a particular variable functionality, e.g., when implementing different variations of an algorithm in separate features, the variability-aware Strategy pattern would be appropriate. Furthermore, we intend to reduce the effort for mapping FRM roles to concrete feature models by utilizing similar mechanisms we used to detect the structure of design patterns in source code to find suitable structures in a feature model realizing the constraints of an FRM, e.g., when implementing the common part of the above mentioned variations of an algorithm in a specified feature, then proposing its child features for mapping the respective FRM roles of the Strategy pattern. In addition, besides proactive and reactive SPL development, we will develop our approach further to cope with extractive SPL development. For this purpose, we will implement refactoring [36] support to create variability-aware design patterns: Violations of a design pattern may be perceived as a bad smell [36] that can be eliminated by restructuring the realization artifact to conform to the specification of the design pattern. Due to the variability-aware nature of the design pattern, the transition from legacy code of a single system to structured reuse within an SPL is eased as the entities of the variability-aware design pattern may easily be associated with individual features of the to-be-created SPL. Finally, we are currently in the process of evaluating our generative technique to instantiate variability-aware design patterns in SPL creation by recreating an SPL version of the design-pattern aware tool JHotDraw14 retrieved from a legacy system by a third party. Acknowledgments This work was partially supported by the DFG (German Research Foundation) under grant SCHA1635/2-2 and by the European Commission within the project HyVar (grant agreement H2020-644298). 14 http://www.jhotdraw.org

34

[1] E. Gamma, R. Helm, R. Johnson, J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software, Pearson Education, 1994. [2] S. Schuster, S. Schulze, I. Schaefer, Structural Feature Interaction Patterns: Case Studies and Guidelines, in: Proceedings of the 8th International Workshop on Variability Modelling of Software-Intensive Systems (VaMoS), VaMoS’14, 2014. [3] S. Schuster, S. Schulze, Object-Oriented Design in Feature-Oriented Programming, in: Proceedings of the 4th International Workshop on FeatureOriented Software Development, FOSD ’12, 2012. [4] S. Schuster, Pattern-Based Software Product Line Design using Role Modeling, Diploma thesis, Technische Universit¨at Braunschweig (2014). URL www.digibib.tu-bs.de/?docid=00060381 [5] C. Seidl, S. Schuster, I. Schaefer, Generative Software Product Line Development Using Variability-Aware Design Patterns, in: Proceedings of the 2015 ACM SIGPLAN International Conference on Generative Programming: Concepts and Experiences, GPCE 2015, ACM, New York, NY, USA, 2015. doi:10.1145/2814204.2814212. [6] M. Couto, M. Valente, E. Figueiredo, Extracting Software Product Lines: A Case Study Using Conditional Compilation, in: 15th European Conference on Software Maintenance and Reengineering (CSMR), 2011, pp. 191–200. doi:10.1109/CSMR.2011.25. [7] C. Krueger, Variation Management for Software Production Lines, in: Software Product Lines, Springer, 2002, pp. 37–48. [8] K. Kang, S. Cohen, J. Hess, W. Novak, A. Peterson, Feature-Oriented Domain Analysis (FODA) Feasibility Study, Tech. rep., DTIC Document (1990). [9] K. Czarnecki, S. Helsen, U. Eisenecker, Formalizing Cardinality-Based Feature Models and their Specialization, Software Process: Improvement and Practice 10 (1) (2005) 7–29. [10] C. K¨astner, S. Apel, M. Kuhlemann, Granularity in Software Product Lines, in: Proceedings of the 30th International Conference on Software Engineering, ACM, 2008, pp. 311–320. [11] I. Schaefer, R. Rabiser, D. Clarke, L. Bettini, D. Benavides, G. Botterweck, A. Pathak, S. Trujillo, K. Villela, Software Diversity: State of the Art and Perspectives, International Journal on Software Tools for Technology Transfer 14 (5) (2012) 477–495. [12] D. Batory, Feature-Oriented Programming and the AHEAD Tool Suite, in: Proceedings of the 26th International Conference on Software Engineering, IEEE Computer Society, 2004, pp. 702–703. 35

[13] I. Schaefer, L. Bettini, V. Bono, F. Damiani, N. Tanzarella, Delta-Oriented Programming of Software Product Lines, in: Software Product Lines: Going Beyond, Springer, 2010, pp. 77–91. [14] D. Clarke, M. Helvensteijn, I. Schaefer, Abstract Delta Modeling, in: Proceedings of the Ninth International Conference on Generative Programming and Component Engineering, GPCE ’10, ACM, New York, NY, USA, 2010, pp. 13–22. [15] D. Riehle, Describing and Composing Patterns using Role Diagrams, in: White Object-Oriented Nights: Proceedings of the 1st International Conference on Object-Oriented Technology, Vol. 96, 1996. [16] T. Reenskaug, P. Wold, O. A. Lehne, Working with Objects: The OOram Software Engineering Method, Manning Greenwich, 1996. [17] D. Riehle, T. Gross, Role Model Based Framework Design and Integration, in: Proceedings of the 13th ACM SIGPLAN Conference on Object-oriented Programming, Systems, Languages, and Applications, ACM, New York, NY, USA, 1998, pp. 117–133. [18] Y. Smaragdakis, D. Batory, Mixin Layers: An Object-Oriented Implementation Technique for Refinements and Collaboration-Based Designs, ACM Transactions on Software Engineering and Methodology 11 (2) (2002) 215– 255. [19] C. K¨astner, S. Apel, S. S. ur Rahman, M. Rosenm¨ uller, D. Batory, G. Saake, On the Impact of the Optional Feature Problem: Analysis and Case Studies, in: Proceedings of the 13th International Software Product Line Conference, SPLC ’09, Carnegie Mellon University, Pittsburgh, PA, USA, 2009, pp. 181–190. [20] E. Tsang, Foundations of Constraint Satisfaction, Academic Press, 1995. [21] D. Benavides, S. Segura, P. Trinidad, A. Ruiz-Cort´es, Using Java CSP Solvers in the Automated Analyses of Feature Models, in: R. Lmmel, J. Saraiva, J. Visser (Eds.), Generative and Transformational Techniques in Software Engineering, Vol. 4143 of Lecture Notes in Computer Science, Springer Berlin Heidelberg, 2006, pp. 399–408. doi:10.1007/11877028_16. [22] D. Benavides, P. Trinidad, A. Ruiz-Cort´es, Automated Reasoning on Feature Models, in: O. Pastor, J. a. Falc˜ao e Cunha (Eds.), Advanced Information Systems Engineering, Vol. 3520 of Lecture Notes in Computer Science, Springer Berlin Heidelberg, 2005, pp. 491–503. [23] D. Batory, Feature Models, Grammars, and Propositional Formulas, Software Product Lines.

36

[24] G. Bracha, W. Cook, Mixin-Based Inheritance, in: Proceedings of the European Conference on Object-oriented Programming on Object-oriented Programming Systems, Languages, and Applications, OOPSLA/ECOOP ’90, ACM, New York, NY, USA, 1990, pp. 303–311. doi:10.1145/97945. 97982. [25] D. Duggan, C. Sourelis, Mixin Modules, in: Proceedings of the First ACM SIGPLAN International Conference on Functional Programming, ICFP ’96, ACM, New York, NY, USA, 1996, pp. 262–273. doi:10.1145/232627. 232654. [26] N. Bouassida, A. Kouas, H. Ben-Abdallah, A design pattern recommendation approach, in: IEEE Second International Conference on Software Engineering and Service Science, ICSESS’11, 2011, pp. 590–593. [27] F. Palma, H. Farzin, Y.-G. Gu´eh´eneuc, N. Moha, Recommendation System for Design Patterns in Software Development: An DPR Overview, in: Proceedings of the Third International Workshop on Recommendation Systems for Software Engineering, RSSE’12, IEEE Press, Piscataway, NJ, USA, 2012, pp. 1–5. [28] D. C. Kung, H. Bhambhani, R. Shah, G. Pancholi, An Expert System for Suggesting Design Patterns - A Methodology and a Prototype, in: T. Khoshgoftaar (Ed.), Software Engineering with Computational Intelligence, Vol. 731 of The Springer International Series in Engineering and Computer Science, Springer US, 2003, pp. 287–318. [29] S. S. Suresh, M. M. Naidu, S. A. Kiran, P. Tathawade, Design Pattern Recommendation System: a Methodology, Data Model and Algorithms, ICCTAI’2011. [30] C. Seidl, I. Schaefer, U. Aßmann, DeltaEcore-A Model-Based Delta Language Generation Framework, in: Modellierung, Modellierung’14, 2014. [31] S. She, Feature Model Synthesis, Ph.D. thesis, University of Waterloo (2013). [32] P. Ebraert, A. Classen, P. Heymans, T. D’Hondt, Feature Diagrams for Change-Oriented Programming, in: ICFI, 2009. [33] D. Wille, S. Schulze, C. Seidl, I. Schaefer, Custom-Tailored Variability Mining for Block-Based Languages, in: Proceedings of the International Conference on Software Analysis, Evolution, and Reengineering (SANER), SANER ’16, IEEE, 2016. [34] S. Holthusen, D. Wille, C. Legat, S. Beddig, I. Schaefer, B. Vogel-Heuser, Family Model Mining for Function Block Diagrams in Automation Software, in: Proceedings of the 16th International Software Product Line Conference (SPLC), SPLC ’18, ACM, 2014, pp. 36–43.

37

[35] D. Wille, Managing Lots of Models: The FaMine Approach, in: Proceedings of the International Symposium on Foundations of Software Engineering (FSE), FSE ’14, ACM, 2014, pp. 817–819. [36] M. Fowler, Refactoring - Improving the Design of Existing Code, AddisonWesley Longman, 1999. [37] S. Schulze, O. Richers, I. Schaefer, Refactoring Delta-Oriented Software Product Lines, in: Proceedings of the 12th annual international conference on Aspect-oriented software development, ACM, 2013, pp. 73–84. um, M. Kuhlemann, G. Saake, Variant-Preserving Refactor[38] S. Schulze, T. Th¨ ing in Feature-Oriented Software Product Lines, in: Proceedings of the 6th Workshop on Variability Modeling of Software-Intensive Systems, VaMoS ’12, 2012. [39] W. Zimmer, Relationships Between Design Patterns, Pattern Languages of Program Design 1 (1995) 345–364. [40] E. Gamma, The Extension Objects Pattern, in: Proceedings of the 1996 Conference on Pattern Languages of Programs, PLoP ’96, 1996. [41] F. Buschmann, Pattern-Oriented Software Architecture: A System of Patterns, Vol. 1, Wiley, 1996. [42] K. Beck, R. Crocker, G. Meszaros, J. Vlissides, J. O. Coplien, L. Dominick, F. Paulisch, Industrial Experience with Design Patterns, in: Proceedings of the 18th International Conference on Software Engineering, ICSE ’96, IEEE Computer Society, Washington, DC, USA, 1996, pp. 103–114. [43] D. B¨aumer, D. Riehle, W. Siberski, M. Wulf, The Role Object Pattern, in: Washington University Dept. of Computer Science, 1998. [44] S. Apel, D. Beyer, Feature Cohesion in Software Product Lines: An Exploratory Study, in: Proceedings of the 33rd International Conference on Software Engineering, ICSE ’11, IEEE, 2011, pp. 421–430. [45] C. K¨astner, S. Apel, K. Ostermann, The Road to Feature Modularity?, in: Proceedings of the 15th International Software Product Line Conference, Volume 2, SPLC ’11, ACM, New York, NY, USA, 2011, pp. 5:1–5:8. [46] J. Hannemann, G. Kiczales, Design Pattern Implementation in Java and AspectJ, ACM SIGPLAN Notices 37 (11) (2002) 161–173. [47] G. Kiczales, E. Hilsdale, J. Hugunin, M. Kersten, J. Palm, W. Griswold, An Overview of AspectJ, in: J. Knudsen (Ed.), ECOOP 2001 – Object-Oriented Programming, Vol. 2072 of Lecture Notes in Computer Science, Springer Berlin Heidelberg, 2001, pp. 327–354. [48] G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C. Lopes, J.-M. Loingtier, J. Irwin, Aspect-Oriented Programming, Springer, 1997. 38

[49] D. Riehle, A Role-Based Design Pattern Catalog of Atomic and Composite Patterns Structured by Pattern Purpose, Tech. Rep. Ubilab Technical Report 97.1. 1., Z¨ urich, Switzerland: Union Bank of Switzerland (1997). [50] J. Reimann, M. Seifert, U. Aßmann, Role-Based Generic Model Refactoring, in: D. Petriu, N. Rouquette, Ø. Haugen (Eds.), Model Driven Engineering Languages and Systems, Springer Berlin/Heidelberg, 2010. [51] G. Florijn, M. Meijers, P. van Winsen, Tool Support for Object-Oriented Patterns, in: ECOOP’97 – Object-Oriented Programming, Springer, 1997, pp. 472–495. [52] A. H. Eden, A. Yehudai, J. Gil, Precise Specification and Automatic Application of Design Patterns, in: Proceedings of the 12th IEEE International Conference Automated Software Engineering, IEEE, 1997, pp. 143–152. [53] F. J. Budinsky, M. A. Finnie, J. M. Vlissides, P. S. Yu, Automatic Code Generation from Design Patterns, IBM Systems Journal 35 (2) (1996) 151–171. ´ Cinn´eide, P. Nixon, A Methodology for the Automated Introduction [54] M. O. of Design Patterns, in: Proceedings of the IEEE International Conference on Software Maintenance (ICSM’99), IEEE, 1999, pp. 463–472. [55] H. Albin-Amiot, Y.-G. Gu´eh´eneuc, R. A. Kastler, Meta-Modeling Design Patterns: Application to Pattern Detection and Code Synthesis, in: Proceedings of the First ECOOP Workshop on Automating Object-Oriented Software Development Methods, 2001, pp. 01–35. [56] A. Dabholkar, A. Gokhale, A Generative Middleware Specialization Process for Distributed Real-Time and Embedded Systems, in: Proceedings of the 2011 14th IEEE International Symposium on Object/Component/ServiceOriented Real-Time Distributed Computing, ISORC ’11, IEEE Computer Society, Washington, DC, USA, 2011, pp. 197–204. [57] A. Dabholkar, A. Gokhale, FORMS: Feature-Oriented Reverse EngineeringBased Middleware Specialization for Product-Lines, Journal of Software 6 (4) (2011) 519–527.

39