Object-Oriented Design in Feature-Oriented Programming
Sven Schuster Sandro Schulze
TU Braunschweig TU Braunschweig
Braunschweig, Germany Braunschweig, Germany
[email protected] [email protected]ABSTRACT depending on the used programming paradigm. For object-
Object-oriented programming is the state-of-the-art program- oriented programming (OOP), abstraction and information
ming paradigm for developing large and complex software hiding play a pivotal role for the foundation of a clear design.
systems. To support the development of maintainable and On the technical side, inheritance but also interfaces are
evolvable code, a developer can rely on different mecha- mechanisms that provide the developer with capabilities to
nisms and concepts such as inheritance and design patterns. realize different levels of abstractions. Additionally, object-
Recently, feature-oriented programming (FOP) gained atten- oriented design patterns exist to provide general solutions
tion, specifically for developing software product lines (SPLs). for complex, recurring problems with [6].
Although FOP is an own paradigm with dedicated language While this is the state-of-the-art for complex, stand-alone
mechanisms, it partly relies on object-oriented programming. software system, the concept of software product lines (SPL)
However, only little is known about feature-oriented design gained momentum in recent years [4, 9]. Different approaches
and how object-oriented design mechanisms and design prin- exist to implement software product lines, which can be di-
ciples are used within FOP. In this paper, we want to raise vided in two categories: annotative and compositional [7]. In
awareness on design patterns in FOP and stimulate discus- this paper, we focus on the emerging paradigm of feature-
sion on related topics. To this end, we present an exemplary oriented programming (FOP), a compositional approach that
review of using OO design patterns in FOP and limitations extends OOP by providing reuse facilities for building prod-
thereof from our perspective. Subsequently, we formulate uct lines at large-scale. Although FOP distinguishes from
questions that are open and that we think are worth to OOP by specific mechanisms such as refinements for imple-
discuss in the context of feature-oriented design. menting software product lines, a clear and evolvable design
is crucial for both approaches, FOP and OOP.
For OOP, well-established design mechanisms (inheritance,
Categories and Subject Descriptors interfaces) and concepts (design patterns) exist while for
H.2.2 [Software Engineering]: Design Tools and Tech- FOP only little is known about design issues. However, we
niques—Object-oriented design methods; D.3.3 [Program- argue that object-oriented design mechanisms and concepts,
ming Languages]: Language Constructs and Features— especially design patterns, can be applied to FOP as well,
inheritance,patterns because of related concepts between FOP and OOP. This, in
turn, inevitably leads to several questions: Do we apply OO
General Terms design patterns within FOP already (but rather implicitly
Languages than on purpose)? Is there a way to make design decisions
such as usage of design patterns explicitly in FOP? Are OO
Keywords design patterns applicable to FOP? What are limitations?
design pattern, feature-oriented programming And are there dedicated feature-oriented design patterns?
With this position paper, we want to stimulate the discus-
sion on these (and maybe forthcoming) questions, because
1. INTRODUCTION we believe that they are important for future work on feature-
When developing software systems, an extensible and oriented design and languages. To this end, we provide a
reusable design is crucial for the durability and maintainabil- review on using OO design patterns in FOP by means of
ity of the system. To achieve such a clear and maintainable different examples. Furthermore, we point out limitations
structure, different mechanisms and design principles exist, that we observed during our review.
In a broader sense, this paper also contributes to an ongo-
ing discussion on modularity and design in FOP [8]. In this
context, we stimulate discussion on the question whether ded-
Permission to make digital or hard copies of all or part of this work for icated feature-oriented design patterns are needed to ensure
personal or classroom use is granted without fee provided that copies are an evolvable and maintainable feature-oriented design.
not made or distributed for profit or commercial advantage and that copies Limitations: With this paper, we do not present fully-
bear this notice and the full citation on the first page. To copy otherwise, to fledged and finished research results. Rather, we want to
republish, to post on servers or to redistribute to lists, requires prior specific
permission and/or a fee.
raise awareness on the role of feature-oriented design and
FOSD’12, September 24–25, 2012, Dresden, Germany. its relation to object-oriented design (patterns). Further-
Copyright 2012 ACM 978-1-4503-1309-4/12/09 ...$15.00.
25
more, we focus on a specific feature-oriented approach called AHEAD [3], FeatureHouse [1], or FeatureC++ [2]. The
FeatureHouse. Finally, we rely on the exemplary design core idea of FOP is to decompose a program into features.
patterns presented by Gamma et al. [6], although other All artifacts (code and non-code) belonging to a certain fea-
realizations of these patterns are possible. ture are modularized within one cohesive unit, called feature
module. A feature is an increment in functionality, visible to
2. BACKGROUND any stakeholder. A feature model describes commonalities
and differences between the different programs of a product
In this section we will provide a short background on
line and thus possible and valid combinations of features.
object-oriented design patterns and the paradigm of feature-
Due to its modular fashion, FOP provides a one-to-one map-
oriented programming.
ping between its implementation units (i.e., feature modules)
2.1 Object-Oriented Design Patterns and the features of a feature model.
During design and implementation, it is common that Feature BaseStack Feature Peak
certain recurring problems emerge, which have to be solved class Stack { ... class Stack {
without decreasing maintainability or reusability. A design void push(int v) int peak() {/*...*/}
pattern is a textual description for such a common prob- {/*...*/} }
int pop() {/*...*/}
lem and its possible solution [6]. Following principles for } Composed class
“good” object-oriented design, patterns aim at improving class Stack { ...
the structure of a program and increasing reusability and Feature Undo int backupPush;
maintainability of the source code by making it more flexible class Stack { ... int pop() {/*...*/}
int backupPush; int peak() {/*...*/}
and more adaptable to changes. Examples for such design void undo() {/*...*/} void undo() {/*...*/}
principles that are reflected by patterns are: void push(int v) { void push(int v) {
• favor object composition over inheritance backupPush=v; backupPush=v;
original(v); /* original */
• program to an interface, not to an implementation }} }}
• encapsulate what varies
While different possibilities exist to realize design patterns, Figure 2: Feature-oriented implementation of Stack
we here focus on the implementation and representation (us- with features Peak and Undo
ing UML class diagrams) originally proposed by Gamma
et al. [6]. Examplary, we illustrate the Strategy pattern [6, In Figure 2, we show an excerpt of a stack product line im-
p. 315 ff.] by means of a class diagram in Figure 1. This plementation with FeatureHouse [1], a language-independent
pattern takes a family of algorithms and makes them inter- approach for FOP, which uses superimposition as its com-
changeable by defining an abstract strategy interface. In position mechanism. Feature BaseStack provides the base
this pattern, the class Context holds an object of type implementation of class Stack. The two other features,
Strategy, which provides the interface to be used. This Peak and Undo extend the functionality of this class. In the
object can be replaced with other objects of the same type, context of FOP, this extension or increment of functionality
resulting in an interchangeable algorithm for the defined is called refinement. Basically, refinements offer the possi-
interface. bility to add or extend classes, for instance, by adding new
Context strategy Strategy methods or fields or changing existing ones. Methods can
be composed using a specified keyword (original in Fea-
+ ContextInterface() + AlgorithmInterface()
tureHouse) to access an already existing method body. As
an example, feature Undo extends method push by adding
an additional statement followed by the original keyword,
ConcreteStrategyA ConcreteStrategyB
which invokes method push of the original class Stack. Fea-
+ AlgorithmInterface() + AlgorithmInterface() ture Peak simply adds the method peak. To generate a
program, the selected features (i.e., the corresponding source
Figure 1: Class diagram of Strategy pattern code) is composed using superimposition. For instance, if
a user selects features BaseStack, Peak and Undo results
Design patterns are classified by their purposes into three into class Stack with four methods (push, pop, peak,
categories of patterns: creational, structural and behavioral undo) and one field.
patterns. Creational patterns describe when and how objects
are instantiated such as the Factory Method [6, p. 107 ff.],
which encapsulates and simplifies the creation of similar
objects. The main concern of structural patterns is the com-
3. COMPARING OBJECT-ORIENTED
position of classes or objects, like the Facade [6, p. 185 ff.], AND FEATURE-ORIENTED DESIGN
which hides the structure of a subsystem behind a new, sim- Object-oriented design mechanisms and patterns are well-
plified interface. Finally, behavioral patterns deal with the understood and commonly accepted as a mean to achieve a
interaction between objects and provide dynamic behavior clear and maintainable design. FOP partly relies on object-
at runtime, like the aforementiond Strategy. oriented concepts and mechanisms. This raises the ques-
tion, how and where both approaches consolidate, especially
2.2 Feature-oriented Programming regarding the design of the underlying programs. In this
Feature-Oriented Programming (FOP) is a paradigm to section, we present some initial thoughts on that question. In
implement software product lines (SPL) in a compositional particular, we compare and contrast inheritance and refine-
way [10]. Different approaches and languages exist to imple- ments and discuss whether (and how) object-oriented design
ment feature-oriented software product lines such as patterns could be applied in feature-oriented programming.
26
3.1 Inheritance versus Refinements 3.2 Design Patterns in FOP
While OOP offers class inheritance as the main language Since FOP and OOP share some language mechanisms,
mechanism to gain variability and abstraction in software object-oriented design patterns should be applicable in fea-
design, FOP additionally offers class refinements to achieve ture-oriented SPLs. Furthermore, refinements should not
feature modularity. In the following, we will distinguish these contradict with language mechanisms used for design pat-
mechanisms. terns such as inheritance or interfaces, for the previously
Both, inheritance and refinements, are mechanisms to mentioned reasons. Hence, we argue that we can use refine-
achieve code reuse and to extend classes, but beyond that, ments to modularize design patterns in terms of features.
they do not have much in common. In Table 1, we provide a In the following, we present examples how design patterns
short distinction of both mechanisms. could be extended or modified using refinements.
Inheritance . . . Refinements . . . Feature Foo
. . . creates a new sub- . . . extend the original class Factory {
class to extend a class class itself Product createProduct(int id) {
. . . achieves variability at . . . achieve variability at if(id == FOO)
return new Foo();
runtime compile time }}
. . . is integrated within . . . are not integrated
Feature Bar
the language within the language
class Factory {
Product createProduct(int id) {
Table 1: Inheritance versus Refinements if(id == BAR)
return new Bar();
else return original(id);
}}
class Stack { ... class PeakStack
void push(int v) extends Stack{
{/*...*/} int peak() {/*...*/} Figure 4: Factory Method extended by new Products
int pop() {/*...*/} } using FeatureHouse
}
class UndoPeakStack In Figure 4, we show an example for creational patterns
class UndoStack extends PeakStack { ... in FOP. In particular, we apply a refinement to a variant
extends Stack { ... int backupPush;
int backupPush; void undo() {/*...*/} of the Factory Method (cf. Section 2.1) by providing the
void undo() {/*...*/} void push(int v) { method createProduct(int id) with feature module
void push(int v) { backupPush=v; Foo and using refinements to add new products. Hence,
backupPush=v; super.push(v);
super.push(v); }}
we offer the possibility of creating products of type Bar
}} only if the feature module Bar is included. Moreover, new
factory methods or whole new factories with their respective
products can be introduced with new feature modules. In
Figure 3: Object-oriented implementation of Stack
the same way, other creational patterns can be refined as
with features Peak and Undo
well. For instance, the Prototype pattern [6, p. 117 ff.] can be
extended using a feature module that adds new prototypes
We illustrate the differences between inheritance and refine- to a list of prototypes.
ment with two code examples in Figure 2 and 3, respectively. Structural design patterns, e.g., Facade (cf. Section 2.1),
The feature-oriented implementation of Stack consists of only are great examples for the benefits of combining patterns
one class that is refined in each feature module (cd. Figure 2). of OOP with FOP. The Facade pattern hides a whole sub-
Hence, for a certain variant, only one composed class exists, system behind a simplified interface. As a result, we may
which contains the whole functionality of the selected fea- use refinements to modify or extend everything within the
tures. In contrast, in our object-oriented implementation subsystem, without interfering any other class, as long as
of Stack, we have to introduce a new class for every feature the interface is not modified.
and every combination of features, resulting in four different Behavioral design patterns such as the Strategy pattern
classes (cf. Figure 3). In a nutshell, extending a class with (cf. Section 2.1, Figure 1), can be extended by new strate-
inheritance always leads to a new subclass, while refinements gies via features. In Figure 5, we show the Strategy in
extend the original class itself. Violet 1 , which is combined with the Prototype. While the
Another difference between both mechanisms is their inte- abstract strategy class Graph offers the interface to grant
gration within the language and their scope. Inheritance is a access to the different prototypes for nodes (and edges), the
language mechanism, which can be used to achieve varying concrete strategies like ClassDiagramGraph provide the
behavior at runtime by creating subtypes and providing inter- corresponding prototypes. Since Violet is refactored in a very
changeability between objects. In our example, all variants fine-grained manner, every prototype is included in its own
of Stack are interchangeable, since they are subtypes of the feature module. Hence, the feature module InterfaceNode
same superclass. In contrast, refinements disappear when introduces the prototype for an interface node (cf. Figure 6).
composing the feature modules at compile time. Hence, they This leads to a one-to-one mapping of features and strategies
allow for selecting which features and thus which refinements as well as features and prototypes. We can even modularize
should be included for a certain variant before this variant is more complex behavioral patterns using refinements. For ex-
generated. Overall, inheritance and refinements can be seen ample, in the Observer pattern [6, p. 293 ff.], the registration
as two different, orthogonal dimensions, which are rather
1
complementing than contradicting. source code on www.fosd.de/fh
27
of different observers could be performed in different feature 4. CONCLUSION AND FUTURE WORK
modules. Design patterns describe recurring problems (and its solu-
tion) in object-oriented design. While there is a considerable
GraphFrame
body of knowledge on design patterns in OOP, only little
+ /* methods using graph */ ClassDiagramGraph is known about design patterns in FOP. In this paper, we
+ getNodePrototypes() : Node[]
addressed this topic and reviewed exemplary (OO) design
patterns from a feature-oriented point of view. We hav show
Graph UseCaseDiagramGraph
by example, that design patterns are applicable, but also
point to possible limitations and open questions on benefits
+ getNodePrototypes() : Node[] + getNodePrototypes() : Node[]
and application of patterns in FOP.
While the main contribution of this paper is to raise aware-
StateDiagramGraph
ness and stimulate discussion, we determined open questions
+ getNodePrototypes() : Node[] during our review of design patterns in FOP that can guide
future research on this topic. In future, we want to ana-
Figure 5: Strategy pattern in Violet lyze existing feature-oriented systems with respect to the
Feature InterfaceNode occurrence of design patterns to determine whether design
public class ClassDiagramGraph { patterns are already used in FOP. Furthermore, the concrete
static { realization of design patterns across different feature-oriented
NODE_PROTOTYPES[1] = new InterfaceNode();
}} languages is part of our future work.
Figure 6: Introducing an interface node in Violet 5. REFERENCES
Since refinements are a structural mechanism, we cannot [1] S. Apel, C. Kästner, and C. Lengauer. FeatureHouse:
expect to change any dynamic behavior of the OO patterns. Language-Independent, Automated Software
Hence, we argue, even though we are able to change the Composition. In Proc. ICSE, pages 221–231. IEEE
behavior of design patterns in a certain way by using refine- Computer Society, 2009.
ments, we only gain advantages on a structural level. [2] S. Apel, T. Leich, M. Rosenmüller, and G. Saake.
3.3 Design Pattern in FOP – Use or Refuse? FeatureC++: On the Symbiosis of Feature-Oriented
and Aspect-Oriented Programming. In Proc. GPCE,
Based on the review of OO design patterns and some initial pages 125–140. Springer-Verlag, 2005.
insights on feature-oriented programs, we briefly address the
[3] D. Batory, J. Sarvela, and A. Rauschmayer. Scaling
questions that we posed at the beginning of this paper. For
Step-Wise Refinement. TSE, 30(6):355–371, 2004.
a more comprehensive overview, we refer to [12].
Do we already apply OO design patterns in FOP? [4] P. Clements and L. Northrop. Software Product Lines –
Recently, we conducted a preliminary analysis on design Practices and Patterns. Addison-Wesley, 2001.
patterns in feature-oriented programs [12]. As a result, we [5] K. Czarnecki and U. W. Eisenecker. Generative
detected design patterns throughout all programs, regardless Programming: Methods, Tools, and Applications. ACM
whether they have been refactored or developed from scratch. Press/Addison-Wesley, 2000.
Hence, we argue that design patterns are already in use with [6] E. Gamma, R. Helm, R. Johnson, and J. Vlissides.
FOP. Nevertheless, a more comprehensive and quantitative Design Patterns: Elements of Reusable Object-Oriented
analysis is necessary to make claims regarding how and which Software. Addison-Wesley, 1995.
patterns are used. [7] C. Kästner, S. Apel, and M. Kuhlemann. Granularity
Are OO design patterns applicable in FOP? Based in Software Product Lines. In Proc. ICSE, pages
on our review and preliminary analysis of feature-oriented 311–320. ACM Press, 2008.
programs, the answer is yes. However, it is open which pat- [8] C. Kästner, S. Apel, and K. Ostermann. The Road to
tern fit very well with FOP and which do not. Furthermore, Feature Modularity? In Proc. FOSD, pages 5:1–5:8.
how concrete implementations look like for different feature- ACM, 2011.
oriented languages has to be investigated. Another point, [9] K. Pohl, G. Böckle, and F. Van Der Linden. Software
even discussed for OO languages, is the question whether Product Line Engineering: Foundations, Principles,
design patterns are always beneficial or might even introduce and Techniques. Springer, 2005.
drawbacks [5]. For instance, Smaragdakis et al. compare [10] C. Prehofer. Feature-Oriented Programming: A Fresh
mixin layers, another approach for realizing compositional Look at Objects. In Proc. ECOOP, pages 419–443.
SPLs, with the Visitor pattern and point out certain char- Springer, 1997.
acteristics where mixins are more advantageous than the [11] M. Rosenmüller, N. Siegmund, G. Saake, and S. Apel.
visitor pattern [13]. Code Generation to Support Static and Dynamic
What are limitations? From our perspective, applying Composition of Software Product Lines. In
behavioral patterns is limited, because these patterns focus Proc. GPCE, pages 3–12. ACM, 2008.
mainly on changing behavior at runtime. Although it has [12] S. Schuster. Design Patterns in Feature-Oriented
been proven by Rosenmüller et al. that such patterns can be Programming. Bachelor thesis, TU Braunschweig, 2012.
used to support dynamic binding [11], it is generally a very
[13] Y. Smaragdakis and D. Batory. Mixin Layers: An
complex task and maybe only possible for certain languages.
Object-Oriented Implementation Technique for
Furthermore, implementing design patterns with features as
Refinements and Collaboration-based Designs. TOSEM,
an additional dimension could be a complex task, especially
11:215–255, 2002.
from a programmer’s comprehension point of view.
28