PuLSE-. MDD distills expertise in the application domain and in implementation ... Being in such a situation, organizations currently like to buy into model-driven.
Optimizing Model-driven Development by deriving Code Generation Patterns from Product line architectures Michalis Anastasopoulos, Thomas Forster, and Dirk Muthig Fraunhofer Institute for Experimental Software Engineering (IESE) Sauerwiesen 6, D-67661 Kaiserslautern, Germany {anastaso, forster, muthig}@iese.fraunhofer.de
Abstract. Model-driven development envisions raising the abstraction level at which software development is performed. To fully realize this vision, technology-specific aspects must be completely hidden from developers. They produce only platform-independent models, which are automatically transformed into executable systems. Model-driven approaches have demonstrated that they may improve current practices; however, they yet did not fully realize their overall vision. In this paper, PuLSE-MDD, a systematic approach for implementing model-driven development, is presented, which combines model-driven development with product line engineering. PuLSEMDD distills expertise in the application domain and in implementation technologies captured in a Product line architecture into executable patterns. These patterns then enable a model-driven development of product line members with optimized code generation. The approach and its benefits are demonstrated by a mobile phone case study.
1
Introduction
Many organizations today feel that their effort spent on developing software deals more with solving specific problems of underlying implementation technologies than with realizing new and innovative features. As a consequence, these organizations mainly build up expertise in specific technologies (that frequently change) rather than in their application domain or in solutions for future markets. Being in such a situation, organizations currently like to buy into model-driven approaches because these approaches promise to take away all technology-specific problems and to enable organizations to focus only on their core business. For instance, Model-Driven Development (MDD) promises to degrade a strategic management decision like the selection of an implementation platform for future products (e.g., J2EE or .Net) into a minor technical detail represented by a simple switch in some code generation tool. From the study of successful applications of model-driven development (cf. [1] and [2]) it becomes clear, that the main advantage is the productivity gain. The latter emerges through the extensive use of generators, which replace cumbersome implementation activities. Hence model-driven approaches may improve development practices; however, they yet do not make organizations independent of underlying implementation technologies.
In this paper we describe PuLSE™-MDD1, a systematic approach to model-driven development that tailors code generation to the goals of a particular organization. Our approach enables the creation of a generator infrastructure, which is driven by the product portfolio of an organization and not by the different implementation technologies that can be employed. The remainder of the paper is structured as follows: Section 2 discusses current model-driven development approaches and limitations. Section 3 introduces product line software engineering as the unique ingredient of our approach. Subsequently the internals of PuLSE-MDD are described in section 4 and section 5 presents an according case study. Section 6 analyzes the practical experience gained so far. The paper concludes in section 7.
2
Model-driven Development
Model-driven Development aims at separating business logic from target platforms. This is achieved through the creation of architectural models that capture only the required business functionality thereby neglecting the underlying technology. In other words the technology constitutes a variation point, which initially is not considered as architecturally important [3]. Furthermore, MDD approaches are supported by generators, which are used for enabling the efficient implementation of the business logic. The efficiency comes from the automated transformation of the respective architectural models into code. The logic behind the transformation can be documented in so-called transformation patterns. Moreover, the generation process is often thought off as step-wise. That means that the architectural models are first being refined towards intermediate implementation models, which are then being translated into code. Current MDD approaches support the abstraction from concrete implementation technologies through meta-models, which basically define domain-specific languages. The meta-models contain platform-independent concepts and their relationships, which can be used to describe a problem space in a given domain. The definition of meta-models is not a trivial task; therefore it is in many cases performed by interest groups or consortia like the OMG. This leads to comprehensive and standardized meta-models; however, it can also result to epistemic meta-models capturing concepts and relationships that are not relevant for the products of a particular organization. Currently, successful MDD approaches are platform-centric and bound to a given implementation technology (such as J2EE). That is, meta-models are fully aligned with the underlying technology. In this case the issues that are initially neglected are decisions about technical characteristics of the already selected platform (e.g. application servers or persistence mechanisms). Therefore these approaches are bound to technology implications, which may overconstrain the business architecture. In essence such MDD approaches are driven by the target platform and not by the envisioned system architecture. This constitutes a 1
PuLSE (Product line Software Engineering) is a registered trademark of the Fraunhofer Institute for Experimental Software Engineering (IESE)
gap between theory of model-driven development, which proposes a waterfall approach, and practice, which in this case proceeds in a bottom-up manner.
3
Product line software engineering and MDD
A software product line is a family of related products designed to take advantage of their common aspects and predicted variability [4]. Product line engineering comprises systematic methodologies for developing software product lines and builds on earlier work in domain engineering, which focused on developing solutions for general domains. Product line engineering, however, strongly focuses on products an organization is going to build by systematically defining the concrete scope within the given domain [5]. Product line engineering has two main phases: The family engineering phase produces generic artifacts that contain variability and are reusable across a complete product line. The application engineering phase produces artifacts that are specific for a concrete product. The goal of the application engineering is, therefore, the derivation of product line members. MDD can take the role of the technological backbone in product line engineering, by accelerating the creation of generic, as well as of product-specific code. However current realizations of this idea concentrate only on the creation of technical platform families. The members of a technical platform family are related to each other only by virtue of the underlying platform (or technology), which in this case is common. Therefore the generator infrastructure is what is mainly reused across such family members. Product line engineering, however, aims at reusing all types of assets, and thus far more than technology-specifics only. Another limitation of current MDD approaches for product lines is the lack of model-driven generators for the family engineering phase. Existing generators process only instantiated domain models, that is models without any variability. Such generators are used throughout application engineering, especially during product implementation. The product line architecture plays a central role in product line engineering since it constitutes the common basis for the software architectures of all product line members. Therefore it embraces the technology-independent business components as well as the technology-dependent generator infrastructures, which adhere to the (different) implementation platforms of the product line. There are several processes for defining product line architectures [6]. This work is based on PuLSE-DSSA [7], which is an integrated, iterative, and quality-centered method for the design and assessment of product line architectures. Up to now, product line engineering has mainly focused on the construction of product line infrastructures and so only a few studies have looked into the usage of these infrastructures for efficiently building products. Product configurators [8] and production processes [9] deal with this issue, but their integration with product line engineering has not been studied adequately. Software factories [10] and product line production plans [11] are further promising approaches in this regard. In essence PuLSE-MDD addresses the three major limitations found in current combinations of MDD with software product lines:
1. 2. 3.
4
Going beyond technical platform families Supporting the generation of generic code Optimizing the usage of product line infrastructures for efficiently deriving products.
PuLSE-MDD
The PuLSE-MDD approach to model-driven development employs an organization’s product line architecture as the source for developing a tailored generative infrastructure. This product line architecture-driven tailoring is what distinguishes our approach from other interpretations of model-driven development. The next sections will present the approach in more detail. 4.1
Code Generation Patterns
For the benefit of tailoring, code generation patterns are derived from the given product line architecture. So tailoring is mainly concerned with the customization and preparation of identified patterns for automation across the product line. In the best case, a pattern set is identified that can transform models of product line members into the respective implementations. In practice, however, implementations must typically be completed manually because it is economically more useful to implement parts of a system manually than to develop and maintain complete but complex pattern sets. Figure 1 provides an overview of PuLSE-MDD. The approach interfaces with PuLSE-DSSA mainly in the realization phase, when the product line architecture is being created.
Figure 1 PuLSE-MDD’s iterative process
PuLSE-MDD supports the realization of architectural components in two parallel activity branches. The left-hand branch designs components, while the right-hand branch identifies and tailors appropriate design patterns and builds an according generative infrastructure. For defining useful patterns, the focus is initially on the identification and classification of similar problems in use-cases and architectural diagrams. Moreover non-functional requirements are analyzed for identifying further pattern candidates. The pattern identification is an iterative and evolving process. In each iteration the degree of generated code is expected to rise. 4.2
Pattern template
Patterns are documented according to the template depicted in Table 1. We provide only the template description at this point; section 5 shows how this template can be applied. The structure is based on the pattern description format proposed by Gamma et al. in [12]. Experience has shown that in most of the cases the patterns, which are being extracted from the product line architecture, are customizations of well-known patterns like those contained in [12]. So, the pattern template has been designed to capture this customization information. Additionally the last two rows of the template support the refinement towards the implementation and the decision about automating the implementation of the given pattern. Intent
Architecture-specific characteristics the pattern addresses The corresponding pattern solution that can be extracted from the product line architecture
Pattern
Tailoring Pattern Structure Translation rules Automation
Customization of the pattern (Graphical) Representation of the tailored pattern (i.e. pattern metamodel) Rules to apply when the pattern is refined towards the implementation level Cost and benefit estimation of creating a generator for this pattern
Table 1 PuLSE-MDD pattern template
4.3
Model-driven product line engineering
Figure 2 shows the framework and application engineering phases as well as the combination with PuLSE-MDD in more detail. In family engineering, PuLSE-MDD supports creating generic implementation artifacts.
Framework Engineering
Application Engineering Product Design
Domain Design
Domain Models
Domain Design Domain Patterns
Instantiate
Define productspecfic architecture
Business Models
Productspecfic models
Infrastructure Models
Product Implementation Business Architecture
contains
Domain Architecture
contains
Domain Implementation
Infrastructure Architecture
Domain Implementation
Instantiate
Will generator pay?
Build Generator
Yes
No
Proceed Manually
Existing or Reference Implementation View
Implement product specific code
Generator Available
Yes
Use Generator
Build Generator
Optimize Manually
No
Intermediate Implementation View
Will generator pay?
Yes
No
Optimize Manually
Legend
Proceed Manually
Activity Workproduct Decision
Domain Implementation
Product Implementation
Figure 2. PuLSE-MDD during family and application engineering
During domain design the product line architecture is created, which contains common business and infrastructure components. The domain patterns, which are created during domain engineering, have a special characteristic: they can embrace variability aspects and this is what distinguishes them from product-specific patterns created during application engineering. The domain implementation process takes the product line architecture as input and decides for each component whether supporting it by a generative infrastructure will be beneficial. The generator construction step consumes previously identified domain patterns and thus enables code generation for those patterns only. In the application engineering phase, PuLSE-MDD supports the generation of product-specific code. First, during product design the product-specific architecture is derived mainly by instantiating the product line architecture (shown as domain models in the above figure). Product-specific patterns can be either instantiated from the domain patterns or they can be extracted from the product-specific architecture. If new patterns are derived they may be integrated with the product line infrastructure. In that way, product-specific enhancements become beneficial for other product line members as well. The inputs to the product implementation step are the instantiated product architecture and the generic code produced before by family engineering. The generic implementation is being instantiated and so parts of the product code are produced. Remaining parts are created by transforming models of the product architecture into code thereby executing a sequence of tailored product-specific patterns. If new product-specific patterns are identified during the product design, developers must decide whether a generative infrastructure for these patterns will pay.
If so, product-specific generators are created and integrated with the overall product line infrastructure, and thus become available to be applied in the context of other product line members as well. Generally, the build time of model-driven generators depends on its input. Standard generators, which cannot process variant model elements, can be built during family engineering if their input is variance-free and possible variations are not considered until application engineering. In other words such generators are built during family engineering but used during application engineering. Table 2 summarizes the different types of generators, which are supported by PuLSE-MDD. Build and Usage Time FE2/FE FE/AE AE/AE
Input (i.e. models) Generic models or Variance-free models reflecting common services Variance-free models (i.e. variability handling is deferred) Product-specific models
Output (i.e. code) Generic or common code Variance-free code Product-specific code
Table 2 PuLSE-MDD generator types
5
Case Study
The case study presented in this section is based on a hypothetical mobile phone company, the GoPhone Inc, a publicly available [13] test bed developed especially for the purpose of validating and illustrating product line methods, techniques, or tools. In the case study, PuLSE-MDD was applied in a reengineering–driven mode. That is, the architecture and the manual implementations of existing components have been analyzed to identify patterns, which in turn were applied to generate code frames for further components in the application layer. Several patterns were identified and implemented with respect to the chosen implementation technology (J2ME) up to a point where the implementation of further patterns has become less economic or, in other words, not useful for defining a first set of code generation patterns. In the following subsections, a rough sketch of the GoPhone architecture is provided first, and then the concrete application of PuLSE-MDD including the generator construction is described.
2
FE = Family Engineering; AE = Application Engineering
5.1
GoPhone Architectural Layers
Figure 3 GoPhone Architectural Layers The GoPhone product line architecture is layered and adheres to the componentoriented style. The hardware abstraction layer and the service layer contain the infrastructure components. The ComponentManager is a mediator and mainly handles the communication and life cycle of business components in the application layer. Business components reside in the application layer and inherit from an abstract component type called PhoneComponent, which defines the common structure of application layer components. Subsequently we will focus on PhoneComponents and especially on the generation of the code parts managing the user interaction. 5.2
Application of PuLSE-MDD
For the identification of existing patterns and candidates for automation we looked in the GoPhone implementation view. For service components like the mediating ComponentManager, automation potential has been estimated as low, as there is only one instance of that type in the architecture. The analysis of the PhoneComponents in contrast showed that it would pay to partially automate the implementation especially because the extension of the application layer components with further components is very likely. 5.2.1 PhoneComponent Analysis Figure 4 presents the conceptual view of an application layer component. The stereotype subject denotes the focus of the diagram according to the principle of locality [14].
Figure 4: Conceptual view of PhoneComponent
Each PhoneComponent uses a data model that optionally can be made persistent. The interaction with the user (menu prompt) is managed through a state machine. Each state of the state machine is associated with a corresponding screen. Figure 5 shows the Java-based implementation view of a calendar component derived from the generic PhoneComponent.
Figure 5: Implementation View of calendar component
The component interface is realized as a class that is compatible with the mediator framework and is located in a root package named after the component (Calendar in this example). The state machine is realized using the state pattern and is implemented in a sub-package called state. The data model resides in the data subpackage. So, the initial pattern set has been produced in two steps: 1. Analyzing the conceptual and the implementation views 2. Analyzing and classifying commonalities using the implementation view of different PhoneComponents and using that information for instantiating the pattern template introduced in section 4.2. Table 3 exemplarily shows the usage of the pattern template for the state machine pattern.
Intent Pattern Tailoring requirements Pattern Structure
Translation Rules
Automation
Due to the small screen size of mobile devices the amount of information displayable and editable in the business components at a time is restricted. An intelligent menu prompt and screen management is necessary. Introduction of a state machine per component that handles each active screen and the according data in an associated state. The pattern structure must reflect the fact that each state manages an associated screen.
1. 2.
Within the package of the PhoneComponent a package “state” is created. Each state specified in the diagram becomes a class. A class that encapsulates all specified states is created. The name of this class is a concatenation of the PhoneComponent’s class name and the string “Statemachine” 3. Each state class specifies an action method where the guards at the transition are evaluated. If there are more transitions from one state ifstatements are created. The state design pattern can be generated from an abstract description.
Table 3: Tailoring the state pattern 5.2.3 Generator realization
The input to the generator is a set of UML models reflecting the application of patterns. These models are instances of meta-models defined during the tailoring of the patterns. Such meta-models have been developed for the specification of the state machine, the component interface as well as different types of user screens and data model elements. The generator architecture is shown in Figure 6. The generator takes state diagrams in XMI format as input. Additionally it uses a set of generic code templates that constitutes the concrete mapping of the input metamodel to the implementation technology. For performing the transformations the generator employs XSLT stylesheets. The organization of the generator and its application is illustrated in the following picture. Each work product is assigned a tuple (A,B), where A denotes the format of the work product and B the abstraction level (PIM stands for platform-independent model and PSM for platform-specific model).
(UML, PIM) Component Specification
(XML, PSM) Generic Assets
Instantiate Generic Component
(XSLT, PSM) Configuration Knowledge
(XML, PSM) Component Specification
Generate State Machine
(Java, PSM) Component State
(XSLT, PSM) Configuration Knowledge
(Java, PSM) Component State Machine
Generate User Interface
(XSLT, PSM) Configuration Knowledge
(Text, PSM) Component User Interface Configuration
(Java, PSM) Component User Interface
Figure 7 Organization and Usage of the GoPhone generator
6
Analysis
The introduction of PuLSE-MDD avoided redundant work and improved significantly the quality of the generated code. This applies especially to state machine and user interface code where programming has proved to be cumbersome and error-prone. Comparing the amount of time spent in preparing and using the generative infrastructure for a set of components and patterns with the amount of time spent in implementing the same architecture manually showed that the generator pays after its application to a few components. In the following we look at the Calendar component mentioned above that for the sake of the validation was first implemented manually and then generated from UML-models. Table 4 shows the results of the comparison. Learning effort for applying the generative infrastructure has been reduced over time as the generator and its documentation were evolving. Initial orientation Time spent in modeling Time spent in implementation and error fixing Generated LOC without comments Total lines of code
Manually implemented Calendar Component 20 to 24 man hours 6 to 8 man hours (without metamodels) Approximately 30 man hours
Generated Calendar Component 8 to 12 man hours About 3 man hours (using metamodels) 3 man hours (Mainly for minor generator fixes)
Approximately 630
630
Approximately 2100
Approximately 2100
Table 4: Manual component implementation vs. generation
The realization of translation rules (cf. Table 3) was generally a time-consuming task. In the following table the effort for automating the state pattern translation rules is shown. GoPhone system size at beginning of PuLSE-MDD Orientation effort (Effort for studying the existing product line architecture) Time spent in the realization of the translation rules including meta model design, XSL scripts and generic templates. State Pattern automation realization (template code and XSL)
Approximately 5000 LOC About 40 to 50 man hours About 40 man hours 430 LOC
Table 5: Effort spent in state pattern implementation
Implementing the generator and realizing six patterns of different size took 100 to 120 man hours without the initial orientation effort. Finally, the following observations could be additionally made: • As we were not involved in the GoPhone development from the beginning the orientation effort was the biggest problem therefore the return on investment occurred not as soon as hoped. • The usage of XML and XSL sped up the generator development although there are open maintainability issues regarding the XSL dialect. • Nevertheless, building the generator infrastructure turned out to be a sound decision because the achieved quality improvements and the relative time saving is expected to increase as the generator improves and further components are developed.
7
Conclusions and Future Work
In this paper, we have presented PuLSE-MDD, an approach for the systematical construction and tailoring of model-driven generative infrastructures for software product lines. The major characteristic of PuLSE-MDD is the use of the given product line architecture as main input. From the experience we gathered using the framework we can conclude that the supported tailoring reduces significantly the overhead of the introduction and set-up of a model-driven generative infrastructure and at the same time it does not neglect any of the advantages of model-driven development. However more practical evaluations are still necessary. Although model-driven development and software product lines are often seen as closely related, this relation has to be further investigated. In particular, the role of model-driven development during framework engineering has to be studied with respect to the variability aspects. This involves the generation of generic code out of generic models but also the construction of generic patterns and according generators. Moreover, understanding and managing the different types of variability, which can be resolved during the step-wise pattern-based refinements, is a challenging task.
8
References
[1] D. Herst and E. Roman, Model Driven Development for J2EE Utilizing a Model Driven Architecture (MDA) - Approach: A Productivity Analysis, TMC Research Report, June 2003 [2] Object Management Group, http://www.omg.org/mda/products_success.htm
MDA
Success
Stories,
see
[3] D.E.Perry, Generic Architecture Descriptions for Product lines, LNCS 1429, Springer, 1998 [4] Weiss, David M., and Lai, Chi Tau Robert: Software Product-Line Engineering: A Family-Based Software Development Process, Addison-Wesley, 1999 [5] J.-M. Debaud and K. Schmid. A Systematic Approach to Derive the Scope of Software Product lines, in the Proceedings of the 21st International [6] Mari Matinlassi, Comparison of Software Product line architecture Design Methods: COPA, FAST, FORM, KobrA and QADA, VTT Technical Research Centre of Finland [7] Joachim Bayer et al., Architekturentwicklung, basierend auf existierenden Systemen, chapter in Böckle, Günter (Ed.); Knauber, Peter (Ed.); Pohl, Klaus (Ed.); Schmid, Klaus (Ed.), Software-Produktlinien. Methoden, Einführung und Praxis, Chapter 13 (in german), dpunkt.Verlag, 2004 [8] Hotz, L. and Krebs, T., Supporting the Product Derivation Process with a Knowledgebased Approach, In Proceeding of Software Variability Management (SVM) -- ICSE 2003 Workshop, Portland, Oregon, USA, May 2003^ [9] Iturls links on Product Development Methodologies, www.iturls.com/English/SoftwareEngineering/SE_eb.asp, iturls, August 2004 [10] J. Greenfield, K, Short, Software Factories: Assembling Applications with Patterns, Models, Frameworks, and Tools, John Willey and Sons, 2004 [11] Gary Chastek Patrick Donohoe John D. McGregor, A Study of Product Production in Software Product lines, Report number CMU/SEI-2004-TN-012, Software Engineering Institute, Carnegie Mellon University, March 2004 [12] Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John, Design Patterns. Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995 [13] Homepage of the kompetenz.de/?21629
GoPhone
case
study
(in
German),
http://www.software-
[14] C. Atkinson et al., Component-based Product Line Engineering with UML, AddisonWesley, 2001. [15] Homepage of Poseidon for UML, http://www.gentleware.com/