The goal of software product lines (SPLs) is to improve productivity, time to market, and the quality of application development by leveraging the commonalities of systems within an application domain while managing their variations. These commonalities and variations may be packaged into a domain-specific platform (DSP), which supports application development through configuration settings or code extensions. Examples of large, vendor-provided DSPs are IBM’s WebSphere Commerce for e-commerce applications and SAP’s R/3 for enterprise resource management systems. The main advantage of creating a DSP is that its planned variability allows for a common product line architecture while its domain focus allows for components that are functionality-rich.
Today’s DSPs are usually implemented using code-centric technologies such as object-oriented frameworks, components, and sometimes even #ifdef preprocessor directives or similar macro-facilities, combined with wizards and form-based interfaces for easy configuration of requirements or features. Applications built on top of such DSPs represent some mixture of platform configuration settings and custom code. The left side of Figure 1 shows a typical DSP, where the horizontal dimension represents the scope of applications that can be derived using the DSP and the vertical dimension represents the easiness of deriving the applications. Cylinders represent applications that can be derived purely through feature configuration, while the rest of the applications on the plane, including the red cross, require custom coding. Custom coding is required if the customer desiring the system indicated by the red cross is not willing to accept any of the next-best purely configured solutions (the closest cylinder to the red cross). Unfortunately, in most DSPs, the scope covered by configuration is relatively sparse, and the transition from configuration to custom coding is rather abrupt, requiring a jump off the top of a cylinder. This situation has been referred to by Cook as the customization cliff (see blogs.msdn.com/stevecook). The idea is that beyond simple configuration facilities such as wizards, which are usually provided to reduce the initial entry barrier, the platform user faces custom coding against the complicated details of the platform’s application programming interface (API). For example, a change to the business workflow of an application generated from a particular feature configuration may require custom code that must interact with different parts of the DSP’s API. Writing such code may require substantial effort since the relevant parts of the low-level API must be learned and used correctly, and the amount of code that must be written may also be substantial. This idea is at odds with the intuitive principle that “easy things should be easy to do and progressively more complex tasks should only get progressively harder to do, not insurmountably harder” (see blogs.msdn.com/garethj).
Model-driven software development [11] has the potential to eliminate the customization cliff in traditional, code-centric implementations of SPLs by offering multi-level modeling and customization as a middle ground between configuration and custom coding, as shown in the right part of Figure 1. In a nutshell, a complex code customization is replaced by more manageable customizations at multiple levels of abstraction. Furthermore, customizations at lower abstraction levels cover an increasing amount of the DSP scope. For example, changing the business workflow of our sample application may be done at the level of the analysis model with no need for custom coding, while interfacing to another application may require custom coding.
After initially illustrating the idea of multi-level modeling of DSP-based applications with a real-world example, we compare and classify customization approaches that can be applied at different levels of abstraction and discuss the trade-offs among them.
Multi-Level Modeling for DSP-Based Applications
The idea of a DSP supporting application engineering with multi-level customization is illustrated in Figure 2. We use an e-commerce DSP as an example. An application engineer first selects or configures the desired business process features, as shown in the top callout. Features available for selection are defined in a feature model [9], which arranges the features in a composition-like hierarchy with some extra constraints. The feature configuration process may be guided through constraint-based facilities, such as consistency checking, choice propagation, and auto-completion [2, 4]. For example, in the top callout, selecting Checkout
would cause the automatic selection of the undecided features Registration
and RequiredFor
due to choice propagation.
In a nutshell, a complex code customization is replaced by more manageable customizations at multiple levels of abstraction.
Based on the feature selection, a default e-commerce application with requirements and design models and code is generated. But for this generation to be possible, feature model must be mapped to generic requirements and design models. One way to achieve such mappings, called feature-based model templates, is to annotate model elements with presence conditions, which are Boolean formulas over features [3, 7]. For a given feature configuration, the presence conditions are evaluated and the elements with false conditions are removed. In Figure 2, since the WishList
feature was eliminated, Create WishList
action, WishList
class and its only association, and the lastWishListTotal
attribute of the Registered
class are eliminated (as indicated by the red color), thereby generating models from model templates with annotations.
Another way, called feature-based restriction, is to constrain models based on a feature configuration [5, 12]. In Figure 2, an OCL constraint below the class diagram states that if the Registration
feature has been eliminated, then instances of Customer
class cannot be direct instances of Registered
, which effectively eliminates Registered
. Since the Registration
feature has been selected, the constraint has no effect. A comparison between feature-based model templates and feature-based restriction is given in [5].
Yet another way of mapping features to models is using aspects. In Figure 2, the top-right callout shows an authentication activity, which is part of a security aspect. A separate rule-based access policy specifies locations in business processes, such as before the Checkout
action, where the authentication activity has to be woven.
The default implementation and models that were generated for the particular feature configuration most probably need to be further customized through extensions or modifications at multiple levels. Changes to one level must be propagated to all other levels or at least the ones below the changed level. Both generation and change propagation are achieved using the discussed feature-to-model mappings, as well as model-to-model and model-to-code mappings, which are studied extensively in the field of model transformation (see [6] for a survey on this topic).
Classification of Customization Approaches
Up to this point, multi-level customization has been discussed in the context of mapping between levels, without addressing how customization at each level occurs. Here, we discuss a variety of customization approaches, which are classified in the table. Customization approaches can initially be divided according to the modeling approach.
Black-Box Modeling Approach. The black-box modeling approach is analogous to using a model compiler, which exposes only the top-level model for customization. We include the black-box approach in our classification as a degenerate case of multi-level customization for the sake of completeness. The black-box approach is effective if all desired systems are expressible in the source modeling language. Platform-specific markups, which are annotations for controlling source-to-target transformations [11], offer limited customization. Escapes, which are fragments in the target notation embedded in the source, enable more customization. For example, in a modeling tool like Rational Rose RealTime, one can embed C++ code for actions in statecharts. Both markups and escapes allow only indirect and limited (preplanned) access to the lower level for customization. A notable drawback of both markups and escapes is that they mix levels of abstraction by directly placing lower-level customizations at a higher level. Comparatively, escapes are more problematic than markups in this respect since a source model can be considered as complete without the markups but not without the escapes.
Multi-Level Modeling Approach. Multi-level modeling affords direct editing of the lower levels for customization. Multi-level modeling may or may not support round-tripping, which propagates lower-level changes to the higher level and higher-level changes to the entire lower level including the customizations. In current practice, most multi-level modeling tools do not offer round-tripping. Another important dimension is whether the customized parts of a layer can be distinguished from the rest of the layer. Indistinguishable customizations without round-tripping are not practical because the customizations will be lost after regeneration. Indeed, current multi-level modeling tools commonly support distinguishable customizations without round-tripping. There are numerous ways to distinguish customizations. A protected region specially marks a customization to prevent regeneration from overriding it. This marking may be done in an implicit way through machinery that keeps track of user’s edits behind the scenes, as in CompuWare’s OptimalJ. Another approach is to separate the customization completely from the generated parts using mechanisms of the modeling or programming language. Such API-centric techniques include subclassing generated classes, invoking generated elements by customized elements or vice versa, and using C#’s partial classes [8]. Yet another approach is to separate customizations into aspects. Protected regions and aspects facilitate unplanned customization since they allow any part of the generated model or code to be changed, unlike API-centric techniques. Although rare due to its difficulty, round-tripping can be achieved by defining a reverse and a forward mapping between two levels that identify the higher-level concepts in the lower level and transforms the higher-level concepts into the lower-level elements respectively. Customization is typically indistinguishable from generated elements in round-tripping, but distinction may conceivably be leveraged to perform more sophisticated round-tripping.
The mappings between features and models discussed previously support any kind of direct customization without round-tripping. We are not aware of any comprehensive round-tripping support in feature-to-model mappings, but it is conceivably similar to model-to-code round-tripping in Framework-Specific Modeling Languages [1].
In multi-level customization, the initial product configuration results in a number of models and code at different levels of abstraction, enabling the engineers to apply customizations at appropriate levels.
Conclusion
We have introduced the customization cliff, a situation in which the application engineers face custom coding after initial product configuration, discussed the reasons behind the customization cliff, and proposed multi-level customization as the solution. In multi-level customization, the initial product configuration results in a number of models and code at different levels of abstraction, enabling the engineers to apply customizations at appropriate levels. We also discussed the need for models to be connected by various kinds of mappings to enable change propagation between models and code. In particular, we discussed mappings between feature models and other models that are specific to SPLs. We also classified different customization approaches ranging from black-box to multi-level approaches and discussed their properties and trade-offs.
Multi-level customization is an existing technique whose value has already been demonstrated through industry support, including OptimalJ. However, multi-level customization involving features has not been explored in practice yet. Although a larger example in the context of a realistic e-commerce DSP within our group demonstrated the scalability of feature-based model templates [10], realizing the vision of multi-level customization from features to models to code remains a future work item that involves many challenges. In particular, multi-level round-tripping, verifying product derivation correctness, and migrating customizations back into the DSP offer significant opportunities for future exploration.
Join the Discussion (0)
Become a Member or Sign In to Post a Comment