ARTICLE IN PRESS Journal of Visual Languages & Computing Journal of Visual Languages and Computing 18 (2007) 560–591 www.elsevier.com/locate/jvlc An approach to precisely specifying the problem domain of design patterns Dae-Kyoo Kim, Charbel El Khawand Department of Computer Science and Engineering, Oakland University, Rochester, MI 48309, USA Received 6 March 2006; received in revised form 22 February 2007; accepted 27 February 2007 Abstract The problem domain of a design pattern describes the problem context in which the pattern can be applied. In general, determining the applicability of a pattern to a particular problem heavily relies on the knowledge and experience the developer has with the pattern. This significantly limits the use of patterns. To address this issue, we propose an approach for rigorously specifying the problem domain of patterns. This approach systematically guides one to develop rigorous specifications of a pattern’s problem domain using a precise notation. The resulting specifications can be used to develop tool support for automatic evaluation of pattern applicability. We describe the approach using the Visitor pattern, and show how the resulting specification can be used to evaluate pattern applicability for a particular problem model. We also demonstrate tool support for the approach. r 2007 Elsevier Ltd. All rights reserved. Keywords: Design pattern; Formalization; Pattern applicability; Problem domain; Reuse; UML 1. Introduction A design pattern encapsulates a proven solution for a class of recurring design problems. Use of design patterns in software development often results in high quality product. In general, design patterns are used during the design phase, and using the right patterns for a given problem becomes an important decision which directly impacts the implementation and the overall quality of the software. A question which naturally arises is, how to determine the right pattern? One answer would be to use the problem domain of patterns. Corresponding author. Tel.: +1 248 370 2863; fax: +1 248 370 4625. E-mail addresses: kim2@oakland.edu (D.-K. Kim), celkawan@oakland.edu (C. El Khawand). 1045-926X/$ - see front matter r 2007 Elsevier Ltd. All rights reserved. doi:10.1016/j.jvlc.2007.02.009 ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 561 A design pattern consists of two components, the problem domain and solution domain. The problem domain describes the problem context where the pattern can be applied, and is often used to determine the applicability of the pattern to a problem. The solution domain describes the structure and collaborations of the pattern solution being applied to the problem. However, there are several barriers, which are not necessarily independent, to using the problem domain to determine pattern applicability. Firstly, there is no clear understanding or definition of what the problem domain is. While the solution domain, which describes the structure and behaviors of the solution that the pattern provides, has been well understood, the problem domain is only understood conceptually without a concrete definition. Secondly, there are many patterns (e.g., see [1]), and it is extremely difficult for a designer to choose the ones that are applicable without any tool support, even for the designer who is highly knowledgeable about patterns. This becomes even more challenging for novice designers who do not have much experience with design patterns. Thirdly, while commonly used pattern descriptions (e.g., [2–6]) help one understand the problem domain, it is extremely difficult to use them in a systematic manner, mainly because of the informal nature of the descriptions and insufficient information about the problem domain. The informality also contributes to the second barrier, where different designers may come up with different lists of applicable patterns for the same design, depending on their interpretation of the informal description. These problems can be effectively addressed by techniques that rigorously specify problem domain. Using rigorous problem specifications, one can systematically and objectively determine pattern applicability. Furthermore, rigorous specifications can facilitate the development of tool support for automatic evaluation of pattern applicability. The rigorous specification of a problem domain requires at least two factors: (1) a clear definition of the term ‘‘problem domain’’, and (2) sufficient information about the given problem domain to be specified. Our intensive literature search found only a little work on specifying the problem domain. This might be because of lack of understanding of the use of the problem domain in software development. The most relevant work is the work by Jackson [7]. In his book, he discusses problem frames which capture a class of simple problems in a broadly defined domain. The concept of problem frames is similar to problem specifications in our work. However, problem frames are aimed at providing a conceptual view of a large domain which is sometimes vague (i.e., rather than formalizing concrete properties [e.g., structures and collaborations of participants, a participant’s properties] of the domain). Thus, problem frames are highly generic and coarse-grained to cover all the problems in the domain. Another relevant work is Lano et al. [8]. They proposed a problem specification for the Abstract Factory pattern as part of pattern transformation where the problem specification is transformed to a corresponding solution specification. However, they did not describe how the problem specification was developed and how the transformation was used. It should be also noted that there has been a lot of work (e.g., [8–14]) on specifying the solution domain of patterns. Potentially, these techniques can be used to specify the problem domain, but we have not found any work on this. In this paper, we propose an approach to systematically specify the problem domain of a pattern in a precise and rigorous manner. In the approach, we first define what the problem domain is, and propose resources that are needed to specify the problem domain, and present techniques that precisely specify the properties of the problem domain using the ARTICLE IN PRESS 562 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 resources. Problem specifications obtained using the approach facilitate the development of tool support for evaluating the applicability of patterns. In the approach, we use the Role-Based Metamodeling Language (RBML), a UMLbased pattern specification notation developed in our previous work [15], to rigorously specify the problem domain. A problem specification of a pattern is used to evaluate the applicability of the pattern to a problem model described in the Unified Modeling Language (UML) [16]. To describe the approach, we use the Visitor pattern in the Gangof-Four (GoF) patterns [3]. We chose the Visitor pattern due to its wide use. The proposed approach can also be easily adapted for other patterns in different templates such as the POSA template [2] and AGCS template [17]. We demonstrate an evaluation of pattern applicability using the problem specification of the Visitor pattern and tool support for automatic evaluation. We also present problem specifications for the Abstract Factory, Adapter and Observer patterns in the Appendix. The rest of this paper is organized as follows. Section 2 describes the definition of problem domain being used in this paper. Section 3 presents an overview of the RBML. Section 4 describes the proposed approach using the Visitor pattern and three problem examples. Section 5 illustrates how the resulting problem specification can be used to evaluate the pattern applicability to a problem model. Section 6 demonstrates tool support for automatic evaluation of pattern applicability. Section 7 discusses related work and Section 8 concludes the paper. 2. What is a problem domain? A problem domain can be defined by precisely defining a design pattern. A design pattern describes a generic solution for a class of design problems. The generic solution is described with variation points for different problems. These variation points defines a set of solutions. A design problem is solved by applying a solution, which defines a transformation from the problem to a solution. Based on this interpretation, we can define a design pattern as a 3-tuple (P, S, d), where P is a set of problem models, S is a set of solution models, and d is the transformation function from P to S. Given the pattern definition, a problem domain P can be defined to be a set of problem models that are solved by the pattern solutions. This definition clearly bounds the scope of a problem domain of a pattern such that only the problems belonging to the problem domain can be addressed by the solution of the pattern. This definition also conforms to the principle of design pattern creation that patterns are found (from solution models), not invented. This implies that there should be corresponding problem models to the solution models which constitute the problem domain. In general, a pattern is described in a template consisting of several sections describing the problem and solution domain. For example, the GoF template [3] and the AGCS template [17] are often used to describe design patterns, and the POSA template [2] for architectural patterns. In this work, we use pattern descriptions in the GoF template due to its popularity, but patterns in other templates can be also used. Table 1 shows the GoF template [3]. Each section in the table describes a specific aspect of the pattern. For example, the Motivation section describes a motivating example of using the pattern, and the Structure section describes the solution structure of the pattern. We partition the sections into two parts; the problem description which describes the problem domain and the solution description which describes the solution domain. The Intent, Motivation, Applicability, Known Uses and Related Patterns sections are the problem description, and the rest to be the solution description. We acknowledge that this ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 563 Table 1 GoF pattern template Pattern name The pattern name conveys the essence of the pattern, and becomes part of design vocabulary. Intent A short statement that states the need for the pattern. Also-known-as Other well-known names for the pattern. Motivation A scenario that illustrates a design problem, and how the pattern solves the problem. Applicability The situations in which the design pattern can be applied, recognition of these situations, and examples of problem designs. Structure A graphical representation of the structure of the participants in the pattern. Participants The participants of the pattern and their responsibilities. Collaborations A description of how pattern participants collaborate to carry out their responsibilities, and interaction diagrams illustrating the sequence of requests and collaborations. Consequences Concerns about how the pattern supports its objectives, trade-offs, the results of using the pattern, and variation aspects of system structure. Implementation Implementation issues such as pitfalls, hints, necessary techniques or language-specific concerns. Sample code Code fragments that guide through implementation. Known uses Examples of the pattern found in real systems. Related patterns Related design patterns and their differences, and how they should be used together. partition is subjective, and one might come up with a different partition. However, we believe that the partition is reasonably agreeable. Two major sections in the problem description are the Motivation and Applicability sections. The example in the Motivation section helps one grasp the problem context and find potential properties of the problem domain. The Applicability section, as its name implies, describes applicable situations which are, in general, described tersely in one or two sentences. The other sections in the problem description discuss fringe information (e.g., known uses, related patterns) that is not directly related to the problem properties, but relevant to the problem domain. It should be noted that the solution description may also exhibit some information related to the problem context, though it is likely to be insignificant. For example, the Implementation section often describes implementation variations depending on different problems, and as such it may provide information about problem variations. 3. Overview of the RBML We use the RBML [15] to specify the problem domain of a pattern as a metamodel that defines the set of problem models, which conforms to the definition of problem domain in ARTICLE IN PRESS 564 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 UML Metamodel is_specialized Pattern Specification Metamodel Level defines defines Model Level Pattern Solution Space UML Model Space Fig. 1. RBML approach. Section 2. The RBML is a UML-based pattern specification language developed in our previous work [15] to support the development of pattern-based UML models. The RBML defines the problem and solution domain of a pattern in terms of roles at the metamodel level. By defining a pattern at the metamodel level, the RBML promotes pattern use at the model-level. This also supports the original intent of design patterns that they should be used during the design phase. A role is a set of constraints, and it has a base metaclass in the UML metamodel. Only instances of the base metaclass that satisfy the constraints can play the role. Thereby, an RBML pattern specification can be viewed a sub-language of the UML that defines a subset of UML models. Fig. 1 illustrates the RBML approach. There are two types of constraints that can be defined on a role, metamodel-level constraints and constraint templates: Metamodel-level constraints specialize the base metaclass of a role to shape the type of model elements that can play the role. They define additional constraints on the UML metamodel, defining a subset of instances of its base metaclass. Only the elements in the subset can play the role. Metamodel-level constraints can be represented either graphically or textually in the object constraint language (OCL) [18]. Constraint templates are parameterized OCL expressions that define model-level constraints (e.g., invariants, pre- and postconditions). A constraint template is instantiated by substituting the roles (i.e., parameters) in the template with the model elements playing those roles. The application model conforming to the pattern must satisfy the instantiated constraints. That is, the application must have constraints that imply the instantiated constraints [19]. A model is said to conform to an RBML specification when the model satisfies both the metamodel-level constraints and constraint templates in the specification. Examples of metamodel-level constraints and constraint templates will be discussed in the following subsection. The RBML provides three types of specifications to capture various functional perspectives of pattern properties [15]: static pattern specifications (SPSs) capturing the ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 565 pattern’s structural properties, interaction pattern specifications (IPSs) capturing the pattern’s interaction behaviors, and statemachine pattern specifications (SMPSs) capturing pattern’s state-based behaviors. In this work, we only make use of SPSs and IPSs. 3.1. Static pattern specifications An SPS specifies a class diagram view of pattern participants, characterizing a family of solution class diagrams of the pattern. An SPS consists of classifier roles and relationship roles. A classifier role has the Classifier metaclass in the UML as its base, and defines a subset of instances of the metaclass. A classifier role may have feature roles that determine the characteristics of the classifier role, and can be connected to other classifier roles by relationship roles which have the Relationship metaclass as the base. Fig. 2(a) shows an example of an SPS that captures a partial solution of the Observer pattern [3]. In the SPS, roles are denoted by the symbol ‘‘j’’. There are two class roles jSubject and jObserver and one association role jObserves connecting the class roles. The jSubject role has the following metamodel-level constraints where the first two are represented graphically in the diagram: 1. The base metaclass Class denoted above the role name constrains that the model elements playing the role must be instances of the Class metaclass. 2. The role multiplicity 1 shown in the right upper corner constrains that there must be only one class playing the role. 3. Classes playing jSubject must be concrete: context jSubject inv: self.isAbstract ¼ false. These constraints must be satisfied by the model elements playing the role. For example, in the class diagram in Fig. 2(b) there are three classes: ClockTimer, AnalogClock and DigitalClock. All these classes are instances of the Class metaclass which is the base of the jSubject role. Thus, they all satisfy the first constraint. These classes are also concrete (therefore their names are not italicized or tagged as abstract), and thus the last OCL constraint is also satisfied. At this point, all three classes are considered to be able to play the jSubject role. However, the jSubject role has one more constraint to be satisfied that Class Role |Subject 1 plays ClockTimer |State: |DateType 1..* time: Time date: Date |Sub 1..* 1 1 |Observes 1..* |Obs 1..1 Class Role |Observer 2..* |Update (|s:|Subject) 1..* 2 AnalogClock 3..* DigitalClock update(t:ClockTimer) drawTime() update(c:ClockTimer) drawTime() Fig. 2. An SPS and a conforming class diagram: (a) an SPS; (b) a confirming class diagram. ARTICLE IN PRESS 566 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 classes playing the role must have attributes playing the jState feature role. This rules out the AnalogClock and DigitalClock class from being able to play the jSubject role, leaving only the ClockTimer class valid. This satisfies the second constraint. The role multiplicity 1..* next to the jState role constrains that there must be at least one attribute playing the role. If a role multiplicity is not shown, the default is 1..*. The jObserver role has only graphical constraints similar to the first two constraints of the jSubject role. A notable property in the jObserver role is the jUpdate feature role. The jUpdate role has a parameter role jo whose type is jSubject. This constrains that the classes playing the jObserver role must have an operation that has a parameter type of a jSubject class. The jUpdate role may be associated with constraint templates defining the semantics of the behavior. For example, the following constraint template may be defined for the jUpdate role: An operation playing the jUpdate role must invoke a GetState operation in a Subject class, assuming that the jGetState behavioral role is defined in the jSubject role. context jObserver::jUpdate(js:jSubject) post: jSubject^ jGetState( ). The ^ symbol denotes the isSent operator in the OCL [18], specifying that a GetState message has been sent to a target Subject class between pre- and postcondition time of a Update operation. The template is instantiated by substituting the role names by model elements playing the roles. In order to play the jUpdate role, operations must have behavior semantically equivalent to the instantiated postcondition. In the class diagram in Fig. 2(b), only the AnalogClock and DigitalClock classes satisfy the jObserver constraints. Having two classes playing the jObserver role satisfies the role multiplicity 2..* of the role that there must be at least two classes playing the role. The jSubject and jObserver roles are connected by an association role Observes through two association end roles jSub and jObs. The association end roles have the following OCL metamodel-level constraints: 1. Association ends playing the jSub role must have an object multiplicity of 1..1: context jSub inv: self.lowerBound( ) ¼ 1 and self.upperBound( ) ¼ 1. 2. Association ends playing the jObs role must have an object multiplicity of 1..*: context jObs inv: self.lowerBound( ) ¼ 1 and self.upperBound( ) ¼ *. It should be noted that the multiplicities in the OCL constraints are ‘‘object’’ multiplicities (as in the UML) which constrain the number of objects playing an object role, not role multiplicities (for details, see [20]). The object multiplicity in the first constraint constrains that the association ends playing the jSub role must have an object multiplicity of 1. The two association ends on the ClockTimer class in Fig. 2(b) are examples that satisfy these constraints. The second constraint on the jObs role is interpreted similarly. The two association ends on the AnalogClock and DigitalClock class have multiplicities of 2 and 3..*, respectively. This satisfies the Obs constraint since the multiplicities are within the range of 1..*. Note that the ClockTimer class playing the jSubject role has a feature (date) that does not participate in the pattern. This is allowed in the RBML as long as the class satisfies the ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 567 role constraints. In fact, in most cases (if not all) it is reasonably expected for models to have application specific properties which are not necessarily participating in the pattern. Having the SPS constraints satisfied, the class diagram in Fig. 2(b) is determined to be structurally conformant to the Observer pattern. 3.2. Interaction pattern specifications An IPS specifies an interaction diagram view of pattern participants describing how they collaborate to carry out the pattern solution. An IPS consists of lifeline roles and message roles. A lifeline role has the Lifeline metaclass as the base, characterizing a set of lifelines. Similarly, a message role has the Message metaclass as its base, defining a set of messages that invoke operations on lifelines. Fig. 3(a) shows an example of an IPS that describes the interactions of the SPS roles in Fig. 2(a). The IPS specifies that an js:jSubject lifeline invokes an jUpdate operation on an : jObserver lifeline, and then the : jObserver lifeline subsequently invokes a jGetState operation back on the js:jSubject lifeline. The filled arrow head on the message roles constrains that messages playing these roles must be synchronous. A sequence diagram is said to conform to an IPS if the relative sequence of the messages playing the message roles is same as the message role sequence in the IPS [21]. Fig. 3(b) shows a sequence diagram conforming to the IPS. The sequence diagram describes the interactions of the classes in Fig. 2(b). Based on the mappings of the SPS and the class diagram in Fig. 2, mappings for the IPS and sequence diagram can be derived as shown in Fig. 3. For example, the a:ClockTimer lifeline plays the js:jSubject lifeline role, because the ClockTimer class plays the jSubject role in Fig. 2. In the mappings, there are two pairs of lifelines (a:ClockTimer and :AnalogClock, a:ClockTimer and :DigitalClock), each of which plays the pair of js:jSubject and : jObserver roles in the IPS. The first pair exchanges the update( ) and getTime( ) messages plays |s:|Subject :|Observer t:ClockTimer :AnalogClock :DigitalClock update(t:ClockTimer) |Update(|s:|Subject) nudge() |GetState() update(t:ClockTimer) getTime() synchronize() getTime() Fig. 3. An IPS and a conforming sequence diagram: (a) an SPS; (b) a confirming class diagram. ARTICLE IN PRESS 568 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 playing the jUpdate( ) and jGetState( ) role. This satisfies the requirement of having messages playing the message roles in the role pair. In the message exchange, update( ) precedes getTime( ). This satisfies the sequencing constraint that messages playing the jUpdate( ) role must precede the messages playing the jGetState( ) role. Given this, the first pair is determined to be conformant to the IPS. The second pair is interpreted similarly. Note that the nudge( ) and getTime( ) messages in the sequence diagram are not participating in the pattern, meaning that they are additional application-specific messages. 4. Proposed approach In most pattern descriptions, the problem domain is described informally. While such informal descriptions may be helpful in communicating and understanding the problem context, it can produce ambiguities making it difficult for developers to determine the applicability. Moreover, informality hinders the development of tool support for the problem domain. In this section, we describe an approach that systematically guides one to rigorously specify the properties of a pattern’s problem domain using a precise notation. Fig. 4 shows the process of the proposed approach for developing a problem specification for a pattern. The following subsections describe each of the activities in the process. 4.1. Collecting pattern resources To create a formal specification of a problem domain, we use two resources; a pattern description that is commonly used for the pattern and examples of known problems that have been solved by the pattern. In most pattern descriptions (e.g., [2–6]), the problem domain is described in terms of a simple motivating example and a brief description of applicable situations where the pattern can be applied. Although such a pattern description helps understand the problem addressed by the pattern, the information given in the description is often not sufficient to formalize the core properties of the problem. To obtain more information about a problem domain, we use a set of known problems for the pattern. Ideally, real world problems are the best resources. However, we find that it is very difficult to find or access information about them. We think this is due to proprietary restrictions and the lack of documentations about problems. Instead, we use easily accessible examples which were developed for education and research purposes. The problems described in these examples are often obvious, which may not be the case in real Collecting Problem Domain Information Understanding the Problem Identifying Properties in Problem Domain Problem Description Identifying Common Properties in Problem Models Problem Models Fig. 4. Process of developing pattern’s problem domain specification. Formalizing Pattern ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 569 world examples. Nevertheless, these examples are adequate for demonstration of the proposed approach. When problem examples are considered, one might have questions like, ‘‘How do we find problem examples?’’ or ‘‘How many problems should be looked at?’’. To find problem examples, we suggest utilizing the problem description. The Motivation and Applicability sections often give inspiration of similar problems in everyday life. Though limited, the Known Uses section also provides some information on real world examples. There is no such fixed value for the number of examples to look at. It depends on the level of reliability desired is the problem specification. The more problem models examined, the higher reliability achieved by confirming that core properties are repeatedly found. The core properties may be found with a small number of examples, but the level of reliability would be low. As more examples are studied, the core properties become clearer. However, it should be noted that the goal of this paper is not to present highly reliable specifications, but to demonstrate the proposed approach. 4.2. Understanding the problem Having a clear understanding of the problem context of a pattern is important in formalizing the problem domain. For an initial understanding of the problem, we found the problem description (consisting of the Intent, Motivation, Applicability, Known Uses and Related Patterns sections, see Section 2) of the pattern very helpful, especially the example in the Motivation section. Motivation examples are usually designed to be intuitive and can be easily found in everyday life. The problems are generalized in the Applicability section describing the circumstances where the pattern can be used. Usually, the circumstances are described briefly in one or two lines. Because of brevity, properties may not be directly observed from the description. Nevertheless, this section provides important clues to identifying the core properties. Real world examples of the pattern are discussed in the Known Uses section. In general, they are not very accessible. However, this section can be used to find other problem examples that are more accessible. The Related Patterns section describes other related patterns. We found that in some cases, related patterns are not only related to the solution, but also to the problem. For example, the Visitor pattern makes use of the Composite pattern in its solution (see [3]), and we found that the Composite pattern solution also participates in the problem of the Visitor pattern. We will discuss this more in Section 4.4. It should be noted that finding such a relation requires complete analysis of the problem domain of a pattern. 4.3. Identifying properties from a problem description In this section, we use the Visitor pattern to show how problem properties can be derived from the problem description of a pattern. The Visitor pattern was chosen for its wide use and the availability of more information on the problem domain than other patterns. In the following, we describe how each section of the problem description of the Visitor pattern can be used to derive the properties of the problem domain. Based on the definition of problem domain in Section 2, we specify the problem domain as a characterization of a set of problems, capturing the common properties of the set. ARTICLE IN PRESS 570 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 Node TypeCheck() GenerateCode() PrettyPrint() VariableRefNode AssignmentNode TypeCheck() GenerateCode() PrettyPrint() TypeCheck() GenerateCode() PrettyPrint() Fig. 5. Node class hierarchy (taken from [3]). 4.3.1. Using the Motivation section The Motivation section of the Visitor pattern uses a compiler example to describe the problem. In the example, a program is represented as an abstract syntax tree, and the compiler performs operations (e.g., type-checking, code generation, pretty-printing) on the nodes in the abstract syntax tree. These operations are specific to the type of the node; that is, the operations in assignment nodes are different from those of variable nodes. Each type of node is represented as a class. Fig. 5 shows a problem model of the compiler example used in the Motivation section described with the description. This diagram shows part of the Node class hierarchy. The problem here is that distributing all these operations across the various node classes leads to a system that’s hard to understand, maintain, and change. It will be confusing to have typechecking code mixed with pretty-printing code or flow analysis code. Moreover, adding a new operation usually requires recompiling all of these classes. It would be better if each new operation could be added separately, and the node classes were independent of the operations that apply to them. For example, a compiler that didn’t use visitors might type-check a procedure by calling the TypeCheck operation on its abstract syntax tree. Each of the nodes would implement TypeCheck by calling TypeCheck on their components (see the preceding class diagram). [3] From the description, one can reasonably derive a property that a problem model should have operations that are distributed across the node classes in the hierarchy. However, it should not yet be taken as a core property until the same is found in other problem examples and confirmed. 4.3.2. Using the Applicability section While the Motivation section describes the problem by a specific example, the Applicability section generalizes the example. Thus, it can be viewed as an informal characterization of the problem domain. As such, the section is an important source for identifying the core properties of the problem domain. The description of the applicability is quoted as follows: Use the Visitor pattern when: (a) an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 571 depend on their concrete classes, (b) many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid ‘‘polluting’’ their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them, (c) the classes defining the object structure rarely change, but you often want to define new operations on the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it’s probably better to define the operations in those classes. [3] The description describes three conditions under which the Visitor pattern can be used. The first two conditions (a) and (b) describe the functional aspects of the pattern, generalizing the structural properties of the problem example in Fig. 5 in Section 4.3.1. The last condition (c) describes the non-functional aspects (e.g., changeability) of the model which was implied in the Motivation section. In this work, we only focus on the functional aspects of patterns. Conditions (a) and (b) can be specified in an SPS as shown in Fig. 6(b), characterizing a structural view of the problem domain. The problem example in Fig. 6(a) is one instance (or realization) of the SPS. The abstract and concrete classifiers in Fig. 6(a) are captured in the SPS by the jAbstractComponent and jConcreteComponent role. These roles have a behavioral feature role CrossCuttingOp which specifies the operations across the component hierarchy. Based on the RBML binding metamodel [21] and the UML metamodel [16], the following defines metamodel-level constraints for the ConcreteComponent role: context jConcreteComponent inv: self.roleBinding ! forAllðb1; b2j (b1.boundInstance.patternType.oclIsTypeOf(Class) and b1.boundInstance.isAbstract ¼ true and b1.boundInstance.BehavioralFeature ! exists (op1 j op.instance.instanceBinding.PatternRole.oclIsKindOf(CrossCuttingOp))) and (b2.boundInstance.patternType.oclIsTypeOf(Class) and Node TypeCheck() GenerateCode() PrettyPrint() conforms_to Classifier Role 1..* |AbstractComponent |CrossCuttingOp() 1..* |Client Generalization Role |ComponentGeneralization 1..* VariableRefNode TypeCheck() GenerateCode() PrettyPrint() AssignmentNode TypeCheck() GenerateCode() PrettyPrint() |Supplier Class Role 1..* |ConcreteComponent Generalization Role |ComponentGeneralization 1..* |Client Classifier Role 1..* |Component |Supplier |CrossCuttingOp() 1..* |CrossCuttingOp() 1..* Fig. 6. An RBML Specification capturing the Structure of the Motivation example: (a) a confirming model; (b) partial visitor problem SPS; (c) a simplified problem SPS. ARTICLE IN PRESS 572 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 b2.boundInstance.isAbstract ¼ true and b2.boundInstance.BehavioralFeature ! exists (op2 j op.instance.instanceBinding.PatternRole.oclIsKindOf(CrossCuttingOp))) and op1.name ¼ op2.name)). The OCL constraint specifies that for any two bindings (b1 and b2) of the ConcreteComponent role and model elements: (1) the bound model element must be an instance (i.e., classes) of the base metaclass (Class) of the role to which the model elements are bound, (2) the classes must be concrete, (3) they must have an operation that is bound to the CrossCuttingOp role, and (4) the bound operations must have the same name. The structures of components are captured by the ComponentGeneralization role. By the definition of generalization roles in the RBML [21], the ComponentGeneralization role specifies not only a single level generalization (as shown in the compiler example), but also multiple levels which can be often found in more complicated structures. In multi-level generalizations, the levels below the top level are considered as instances of the ComponentGeneralization role. The jClient and jSupplier roles have a role multiplicity of 1..1 (not shown for simplicity) based on the definition of Generalization in the UML. The mapping between the compiler model and the SPS in Fig. 6 shows that the compiler example conforms to the SPS. This means that the model is a member of the problem set characterized by the SPS. Fig. 6(c) shows a simplified version of the SPS by folding the Component hierarchy. 4.3.3. Using the Known Uses section The Known Uses section shows real world examples that use the pattern. However, descriptions of these examples are usually terse, and it is quite difficult to find more information elsewhere. This makes it difficult for the examples to be used directly in this work. Instead, we use them indirectly as a clue to find other examples that exhibit more information about the problem and have better accessibility. We also use these examples to find the properties of the problem domain. The Known Uses section in the Visitor pattern discusses two examples, the Smalltalk-80 compiler and IRIS Inventor. Based on these examples, we found other similar problems, such as pretty-printing and rendering engine examples. Section 4.4 describes these examples, and show how they are used to find the problem properties of the Visitor pattern. 4.3.4. Using the Related Patterns section The Related Patterns section discusses other patterns related to the pattern in one way or another. For example, the solution of one pattern may be part of another pattern’s solution or problem. The Visitor pattern describes the Composite and Interpreter patterns as its related patterns: Composite (163): Visitors can be used to apply an operation over an object structure defined by the Composite pattern. Interpreter (243): Visitor may be applied to do the interpretation. This description implies that a solution (an object structure) of the Composite pattern and a solution (an express structure) of the Interpreter pattern are problems of the Visitor ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 573 pattern. From this, one can infer that the solutions of these patterns should be related to the problems of the Visitor pattern. The Visitor pattern is also known to use the Composite pattern in its solution (see the Sample Code section), which we confirmed in our previous work [15]. In this work, we will show the other case where the Composite solution is being part of the problem of the Visitor pattern, which confirms the Related Patterns description. 4.4. Identifying properties from problem models While the problem description of a pattern provides necessary information to understand the problem context of the pattern, it is often not sufficient to derive the core properties of the problem domain. To obtain more information about a problem domain, we use problem examples. Given the definition of problem domain in Section 2, problem examples are the best resources to find information about the problem domain. Using problem examples, we observe characteristics that are common to them, and derive properties of the problem domain from the characteristics. In addition to the motivating example in the Visitor pattern, we will use three more examples found in the literature, a rendering engine [22,23], pretty printing [3] and word counter [24]. We developed the problem models of these examples as shown in Fig. 7. Fig. 7(a) shows a partial model of a rendering engine system for drawing pictures that are composed of graphics objects such as lines, rectangles and points. The graphics objects may be edited by tools like a rasterizer or a shape clipper. The sequence diagram describes a drawing line scenario based on the drawing structure in the figure. In the sequence diagram, a window requests drawing lines on the structure, and the request is cascaded to the components in the structure. The Picture component, which is composite, receives the request and subsequently sends the request down to its line sub-components which are also composite. A line component further delegates the request to its point sub-components. Fig. 7(b) shows a partial model of a word counter that counts words in a document by line and paragraph. The structure in the figure shows a document structure that has one paragraph containing two lines, one of which contains two words and the other one contains one word. A word counting scenario is shown in the sequence diagram based on the document structure. In the diagram, a word count request is sent to the document structure, and the request is passed to the document, the top-level composite component. The request is delegated all the way down the structure until it reaches the primitive component, a word. Fig. 7(c) shows a partial model of a pretty-printing application that prints mathematical expressions in a nice looking manner. An example of pretty-printing is inserting regular spaces between the components (e.g., separators, operands, operators) in expressions or making indentations. The sequence diagram in the figure shows a prettyprinting scenario using the given statement structure. When a pretty-printing request is received, the drawing structure propagates the request to its components. Even though the three examples are very different in their context, they have certain common characteristics. We have observed the following common properties from the examples: Hierarchical property: The class diagrams of the examples in Fig. 7 show a hierarchy of components which may be composite or primitive. In the rendering engine, the class diagram has a two-level hierarchy of drawing object classes, and in the word counter, the class diagram has a three-level hierarchy of document element classes, and in the prettyprinting, the class diagram has a single-level hierarchy of statement component classes. ARTICLE IN PRESS 574 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 Fig. 7. Problem models: (a) rendering Engine; (b) word counter; (c) pretty printing. Generalization Role |PGeneralization 0..* Generalization Role |CGeneralization 0..* |PClient |PSupplier Classifier Role 1..* |Primitive Association Role |Composed_Of 1..* |Primtv 1..1 |Compst 1..* |CClient Classifier Role 1..* |Composite |CSupplier {XOR} Fig. 8. An SPS capturing component hierarchies. From this observation, we can derive a property that a problem model is likely to have a hierarchy of component classes. This property can be specified as in the SPS in Fig. 8. In the SPS, the Primitive and PGeneralization roles capture the hierarchies of primitive components, and the Composite and CGeneralization roles capture the hierarchies of composite components. As an example, in the rendering engine, the hierarchy of the Shape, Line and Rectangle is an instance of the Composite and CGeneralization roles. The ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 575 composition relationship between the primitive and composite hierarchy is specified by the Composed_Of role. The multiplicity 1..1 on the Primtv association end role constrains that there must be exactly one association end on a classifier playing the Primitive role. This should not be confused with object multiplicities (see Section 3). The Compst association end role is interpreted similarly. The XOR in the SPS constrains that a classifier cannot play both the Primitive and Composite roles at the same time. There may be cases where no component hierarchies exist, for example there is only one primitive or composite component. To capture such a case, we make the PGeneralization and CGeneralization roles optional by setting their role multiplicity to 0..* allowing no hierarchy. Also, the Composite role could be specified as optional. However, we think that without composite elements, one would not be motivated to use the Visitor pattern, and therefore we do not take this into account. The structural property found in these examples is a refinement of the component structure in Fig. 6. This confirms that components are likely to have hierarchies. Fig. 9 shows a full mapping to the SPS for the rendering engine example. In the figure, the Shape, Line and Rectangle classes play the jComposite role, and the generalizations in the classes play the jCGeneralization role. The Point class plays the jPrimitive role, and the composition relationship between the Shape and Point class plays the jComposed_Of role. Notice that the DrawObject class and the composition relationship between the DrawObject and Picture classes do not play any role. This could mean two things. Either the SPS is incomplete or they are application-specific properties not participating in the pattern. At this point, we do not know which one is the case; this can be determined after the final SPS has been developed. Composite property: The class diagrams in the problem models show that a composite component itself may be an element of another composite component. For example, in the word counter example, a document may be composed of other documents, or it may contain paragraphs and lines which are also composite. Another example is found in the Generalization Role |PGeneralization 0..* Generalization Role |CGeneralization 0..* |PClient |PSupplier Classifier Role 1..* |Primitive Association Role |Composed_Of 1..* |Compst 1..* |Primtv 1..1 {XOR} plays |CClient Classifier Role 1..* |Composite DrawObject Line Rectangle Shape Point Picture Fig. 9. An SPS capturing component hierarchies. |CSupplier ARTICLE IN PRESS 576 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 Classifier Role 1..* 1..1 |Comp |Component |CPSupplier |CCSupplier Generalization Role |CCGeneralization 1..* Generalization Role |CPGeneralization 1..* Generalization Role |CGeneralization 0..* Generalization Role |PGeneralization 0..* |PClient |PSupplier |CCClient |CPClient Classifier Role |Primitive 1..* {XOR} Association Role |Composed_Of_C |CClient Classifier Role 1..* |Composite |CSupplier 1..* |Compst Fig. 10. An SPS capturing composite property. pretty printing example where a statement may be composite of other statements. This observation leads to a property that a problem model is likely to have composite components that consist of other composite components. This property can be captured as shown in Fig. 10. In the SPS, the jComponent role is added to the SPS in Fig. 8 with the following constraint: context jComponent inv: - - Classes that play the Component role must be abstract. self.isAbstract ¼ true. This enforces that only abstract classifiers (abstract classes or interfaces) can play the role. This constraint can also be visualized by italicizing the role name as shown in the SPS. By adding the jComponent role, the unmapped abstract class DrawObject in Fig. 8 now can be mapped to the jComponent role. The jComponent role also reestablishes the jComposed_Of relationship role in Fig. 8 from the Primitive and Composite role to the jComponent and Composite role. This enables capturing not only the structure of composite and primitive components, but also the structures of composite components that consist of other composite components. With the new establishment, the composition relationship between DrawObject and Picture in Fig. 9 now can be mapped to the jComposed_Of role. Component structure property: From the problem models, one can also observe that request delegations are based on a particular object structure (shown in the middle of each example in Fig. 7) composed of instances of the component classes in the class diagram. This structure is managed by a certain class, for example the DrawingStructure class in the rendering engine system, the DocumentStructure class in the word counter application, and the StatementStructure class in the pretty printing application. This leads to a property that a problem model should have a class that manages the object structure for delegating a request. This property can be specified as shown in Fig. 11 by adding a new classifier role ComponentStructure to Fig. 10. The ComponentStructure role is associated with the Component role via an association role Consists_Of that has two association end roles jCompStruct and jElem. The following OCL expressions define metamodel-level constraints for these roles: ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 577 Association Role |Consists_Of 1..* Class Role 1 Classifier Role1..* 1..1 |Comp |ComponentStructure 1..* |CompStruct |Component |Elem 1..1 |CPSupplier |CCSupplier Generalization Role |CCGeneralization 1..* Generalization Role |CPGeneralization 1..* Generalization Role |CGeneralization 0..* Generalization Role |PGeneralization 0..* |PClient |CPClient |PSupplier Classifier Role1..* |Primitive Association Role 1..* |Composed_Of |CCClient |CClient {XOR} Classifier Role 1..* |Composite |CSupplier 1..* |Compst Fig. 11. An SPS capturing composite component property. Class Role 1 |ComponentStructure Association Role |Consists_Of 1..* Classifier Role 1..* 1..1 |Comp |Component |Elem 1..1 |CrossCuttingOp() 1..* |CPSupplier |CCSupplier 1..* |CompStruct Generalization Role Generalization Role |CCGeneralization 1..* |CPGeneralization 1..* Association Role Generalization Role Composed_Of 1..* |CGeneralization 0..* | Generalization Role |PGeneralization 0..* |PClient |PSupplier |CCClient |CClient |CPClient Classifier Role1..* |Primitive |CrossCuttingOp() 1..* {XOR} Classifier Role 1..* |Composite |CSupplier |CrossCuttingOp() 1..* 1..* |Compst Fig. 12. An SPS capturing client property. Classes playing the jComponentStructure role must be concrete. context jComponentStructure inv: self.isAbstract ¼ false. Association ends playing the jCompStruct role must have an object multiplicity of 1..1. context jCompStructinv: self.lowerBound( ) ¼ 1 and self.upperBound( ) ¼ 1. Association ends playing the jElem role must have an object multiplicity of 1..*. context jElem inv: self.lowerBound( ) ¼ 1 and self.upperBound( ) ¼ *. Cross-cutting property: Another property observed from the problem models is that the operations (e.g., draw( ), countWord( ), prettyPrint( )) are defined across the component hierarchies in the class diagrams. These operations are similar in semantics, but tailored to the specific context of the examples. From this observation, a property can be defined that a problem model should have operations defined across the component hierarchy. Fig. 12 shows an SPS that specifies the cross-cutting property by adding a behavioral role CrossCuttingOp to the role hierarchy in Fig. 10. This property postulates that classifiers playing the Component role must have at least one abstract method playing the CrossCuttingOp abstract role, and classifiers playing the Primitive and Composite roles must have at least one concrete method playing the CrossCuttingOp concrete role. This property confirms the CrossCuttingOp role identified in Section 4.3.2, and thus the associated metamodel-level constraint for the role is retained. ARTICLE IN PRESS 578 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 |ComponentTravel :|Client Travel |obj:|ComponentStructure |CrossCuttingOp() repeat i=1..NumOfComponents or [Composite] |CrossCuttingOp() |c[i]: |Composite |Primitve Travel |obj = |c[i] [Else] |CrossCuttingOp() Fig. 13. A Visitor pattern problem IPS. Dynamic property: The properties that have been identified so far are structural properties observed from the class diagrams of the examples. One can also observe behavioral properties from the sequence diagrams of the models. One property we observe from the sequence diagrams is the recursive calls for the cross-cutting operations in the component hierarchies. This is captured by the IPS shown in Fig. 13. The IPS specifies that a client requests a cross-cutting operation on a component structure, and the component structure delegates the request to the components in the structure. If a component is composite, then the component itself plays the role of the component structure of its own sub-components, and delegates the request to them recursively until it reaches a primitive component. This is specified by the repeat and or fragments. The repeat fragment defines the number of occurrences of delegations, and the or fragment defines the recursive calls. The repeat and or operators are RBML operators which are metamodel-level constraints, and should not be confused with the model-level operators (e.g., loop, alt) in the UML 2.0. The roles in the IPS have the default multiplicity 1..* which is not shown for simplicity. Some part of the behaviors in the IPS can be also specified as a constraint template. For example, the following constraint template could be defined for the CrossCuttingOp behavioral role in Fig. 12: context jComposite :: jCrossCuttingOp( ) post: jComp.jComposite^ jCrossCuttingOp( ) and jPrimitive^ jCrossCuttingOp( ). The postcondition postulates that the execution of a CrossCuttingOp operation in a Composite class must subsequently invoke a CrossCuttingOp operation in its subcomposite and primitive components. The template is populated when the roles in the ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 Class Role 1 |ComponentStructure Association Role |Consists_Of 1..* |CompS 1..1 |Clnt 1..* Class Role 1 |Client Classifier Role 1..* 1..1 |Comp |Component |Elem 1..1 |CrossCuttingOp() 1..* |CPSupplier |CCSupplier 1..* |CompStruct Association Role |ClientComp 579 Generalization Role |CCGeneralization 1..* Generalization Role |CPGeneralization 1.. * Generalization Role |CGeneralization 0..* Generalization Role |PGeneralization 0..* |PClient |PSupplier |CPClient Classifier Role 1..* |Primitive |CrossCuttingOp() 1..* Association Role |Composed_Of 1..* |CCClient |CClient {XOR} Classifier Role 1..* |Composite |CSupplier |CrossCuttingOp() 1..* 1..* |Compst Fig. 14. A Visitor pattern problem SPS. template are bound to model elements in a specific application context, and an operation playing the jCrossCuttingOp role must possess a postcondition that implies the populated constraint [19]. It should be noted that the dynamic property could not be found using solely the problem description of the Visitor pattern, which demonstrates the need of problem examples to fully analyze the problem domain. Client property: From the sequence diagrams, one can observe another structural property that there must be a client who initiates the request and communicates with the component structure. We specify this property by adding a classifier role jClient and an association role connecting the Client role to the ComponentStructure role to the SPS in Fig. 12 specified. Fig. 14 shows the property specified. In the SPS, the role multiplicity 1 on the Client is made based on the observation that the problem models have only one client. In order to initiate a request, the client must be concrete. This is specified as follows: context jClient inv: self.isAbstract ¼ false. This is the last property that we could find from the Visitor pattern description and problem examples, and the SPS in Fig. 14 is our final problem SPS for the Visitor pattern. In the SPS, we found an important fact that the Component structure is very similar to the solution structure of the Composite and Interpreter patterns. This implies that the solutions of these patterns are potential problems of the Visitor pattern. This supports the claim [3] that the Visitor pattern can be used for localizing cross-cutting operations in components in the Composite pattern. We found another example where the solution structure of the Mediator pattern is found in the problem structure of the Observer pattern (see Appendix C). These findings reveal that patterns are related not only to solution domains (as shown in the GoF book [3]), but also to problem domains. In order to take full advantage of patterns, there should be a study on establishing a complete relationship amongst patterns including both problem domains and solution domains. As shown in the Visitor pattern, some properties (e.g., Dynamic property, Client property) could be found only when multiple perspectives (class diagrams and sequence diagrams) of the problems were considered. As such, it is possible that more properties could be found if other perspectives (e.g., state-based behaviors) are considered. ARTICLE IN PRESS 580 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 When formalizing any domain that is unclearly bounded, we have to make a trade-off between formality and the scope of the domain. That is, the domain scope should be tailored to be clearly bounded. The same applies to the problem domain of design patterns. The presented problem specification of the Visitor pattern captures only a subset of the problem domain, and thus it should not be considered as a complete specification for the entire problem domain which we believe is nearly impossible to achieve. It should be also noted that the presented problem specification is not the ‘‘only’’ problem specification for the given resources. One may very likely come up with a different specification, depending on his/her interpretation of the resources. The goal of this paper is not to develop a correct or complete specification of the Visitor pattern, but to propose an approach to develop a problem specification. We have also used the proposed approach to develop problem specifications for the Abstract Factory, Observer and Bridge patterns which are shown in Appendix A, B and C. 1 Class Role |ComponentStructure Association Role |Consists_Of 1..* 1..* |CompStruct Classifier Role 1..* |Component |Elem 1..1 |CrossCuttingOp() 1..* |CompS 1..1 |CPSupplier Association Role |ClientComp Class Role |Client |CCSupplier Generalization Role |CPGeneralization 1..* |Clnt 1..* 1..1 |Comp Generalization Role |CCGeneralization 1..* Generalization Role |PGeneralization 0..* 1 |PClient Generalization Role |CGeneralization 0..* |CCClient |CPClient Classifier Role 1..* |Primitive |PSupplier |CClient Classifier Role 1..* |Composite {XOR} |CrossCuttingOp() 1..* |CrossCuttingOp() 1..* Association Role |Composed_Of 1..* |CSupplier 1..* |Compst Visitor Problem SPS DrawingStructure Window addObject(object:DrawObject) a draw() plays 1 ShapeClipper b 1..* DrawObject c setClip(shape:Shape) Rasterizer d draw() getBound():Rectangle Line i draw() Rectangle draw() e f g Point Shape j draw() draw() fillShape() h Picture draw() k Rendering Engine Class Diagram Fig. 15. Conformance of rendering engine class diagram to the Visitor problem SPS. ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 581 5. Evaluating pattern Applicability So far, we have described techniques for formalizing the problem domain of a pattern. The goal of the techniques is to enable systematic evaluation of the applicability of a pattern for a given problem. In this section, we will demonstrate how the Visitor pattern problem specification in Section 4 can be used to evaluate the applicability of the rendering engine model in Section 4.4. Fig. 15 shows the conformance of the rendering engine class diagram in Fig. 7(a) to the Visitor problem SPS in Fig. 14. The dashed arrows in the figure denote the mappings between the roles and the model elements playing the roles. The following are notable points in the conformance: The Picture, Shape, Line and Rectangle classes can play the jComposite role because their instances are composite. For example, a picture is a composite of shapes, and a shape is a composite of points. Also, these classes have a concrete cross-cutting operation draw( ) that can play the jCrossCuttingOp role, assuming that the draw( ) operation has a postcondition that implies an instantiation of the jCrossCuttingOp constraint template in Dynamic Property in Section 4.4. The Point class can play the jPrimitive role because points are primitive components, and the class has a concrete cross-cutting operation draw( ) that can play the jCrossCuttingOp role. The fact that the three classes Shape, Line and Rectangle play the jComposite role satisfies the multiplicity constraint 1..* of the role. The generalization relationships in these classes play (are instances of) the jCGeneralization role on the jComposite role. The association between the DrawingStructure and DrawObject classes can play the jConsists_Of role because its association ends have object multiplicities (1, 1..*) which satisfy the OCL metamodel-level constraints of the jCompStruct and jElem roles in Component Structure property. The Window class can play the jClient role because a) it is a concrete class, which satisfies the OCL metamodel-level constraint of the jClient role in Client Property, and b) it is associated with the DrawingStructure class playing the jComponentStructure role, which satisfies the graphical constraint in the SPS that the class playing the jClient role must be associated with classes playing the jComponentStructure role. The composition relationship between the Shape and Point classes can play the jComposed_Of role inherited from the jComponent role to the jPrimitive role, because the Shape and Point classes play the jComposite and jPrimitive roles, respectively. Given the structural mappings in Fig. 15, the behavioral mappings between the sequence diagram of the rendering engine and Visitor problem IPS can be determined as shown in Fig. 16. In the figure, the lifelines in the sequence diagram are instances of the corresponding classes in the class diagram, and thus they are mapped to lifeline roles associated with the classifier roles in the SPS that are played by the classes. For example, the :Window lifeline is mapped to the : jClient role, because the type (Window) of the lifeline in the class diagram plays the Client role in the SPS. The recursive calls in the sequence are mapped to the CrossCuttingOp role in the repeat and or fragments in the IPS, and their message sequences preserve the sequence of the message roles in the IPS. This determines that the sequence diagram conforms to the IPS. ARTICLE IN PRESS 582 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 |ComponentTravel :|Client Travel |obj:|ComponentStructure |CrossCuttingOp() repeat i=1..NumOfComponents or |c[i]: |Composite |Primitive [Composite] Travel |obj = |c[i] |CrossCuttingOp() [Else] |CrossCuttingOp() Visitor Problem IPS plays sd DrawLine :Window :DrawingStructure :Picture :Line :Line :Point :Point :Point :Point draw() draw() draw() draw() draw() draw() draw() draw() Rendering Engine Sequence Diagram Fig. 16. Conformance of rendering engine sequence diagram to the Visitor problem IPS. The conformance of the rendering engine example to the Visitor problem specification concludes that the Visitor pattern can be applied to the rendering engine model. It should be noted that even if a problem model does not conform to the problem specification, it is most likely that the pattern can be applied to the model. This implies that according to the definition of problem domain in Section 2, the problem model is a valid problem in the problem domain, but not a member in the problem set characterized by the specification. ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 583 6. Tool support We have demonstrated a manual evaluation of pattern applicability in Section 5. As evident in the demonstration, a manual evaluation can be time-consuming, error-prone and complicated. Thus, tool support is necessary in order to facilitate the evaluation of pattern applicability. In our previous work [25], we have developed a prototype tool, RBML conformance checker (RBMLCC), for evaluating the conformance of a UML model to the solution of a pattern described in the RBML. The tool was developed as a plug-in of IBM Rational Rose, a widely used UML modeling tool. RBMLCC takes a UML model and a solution specification as input. If the model is evaluated as conforming to the solution specification, this means that the model is a solution model of the pattern. In this work, we utilize RBMLCC to evaluate the pattern applicability of a problem model. Instead of a solution specification, a problem specification is input to the tool. Since both problem specifications and solution specifications are described in the same notation, the Fig. 17. Visitor pattern problem SPS. Fig. 18. RBMLCC: (a) RBMLCC; (b) Execution trace. ARTICLE IN PRESS 584 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 tool can take either of them. In the following, we will show how RBMLCC can be used to evaluate the applicability of the Rendering Engine example to the Visitor pattern. Fig. 17 shows the Visitor problem SPS drawn in Rational Rose. Because the RBML uses the UML notation for describing patterns, RBML specifications can be drawn by most UML modeling tools that can tolerate some minor variations such as the bar symbol in role names. After the problem SPS has been built, it is exported as a package into a pattern library (directory). When the rendering engine model is loaded and ready for evaluation, the Visitor package is imported into the model. After the package is loaded, RBMLCC becomes enabled for execution. This is shown in Fig. 18(a). RBMLCC implements a divide-and-conquer algorithm [25] to evaluate pattern conformance. In the algorithm, the rendering engine model is decomposed into model blocks, and the problem SPS into role blocks. Each model block is evaluated against role blocks for local conformance, aiming that every role block must be satisfied. When all role blocks are evaluated as satisfied, the pattern as a whole is evaluated for the overall conformance of the model. Fig. 18(b) shows part of the execution trace of the evaluation. The upper part of the trace shows the invalid mappings filtered out by the algorithm from the initial mappings which resulted from the local evaluation of model blocks and role blocks. The lower part shows the final mappings which correspond to the mappings shown in Section 5. In case of non-conformance, one can easily identify the cause of violations using the trace. Rational Rose has two limitations that impact the features of RBMLCC. One is the lack of OCL support. Because of this, RBMLCC does not support pattern constraints expressed in the OCL. To mitigate this, OCL constraints are specified through the property windows in Rational Rose, and the current version of RBMLCC is designed to access them through the windows. In the next version, we plan to adopt the OCL support for Rational Rose developed by Shen and Low [26] to overcome this limitation. The other limitation is the lack of support for association inheritance. That is, associations are not inherited through generalization relationships. Because of this limitation, the mapping of the association k and the Composed_Of role in Fig. 15 could not be established. To mitigate this, we implemented support in RBMLCC for single-level association inheritance which is the most commonly found. We plan to support multi-level association inheritance in the subsequent version. We are also investigating migrating RBMLCC to an open source platform such as Eclipse where the above lack and other potential needs (e.g., code generation) can be better supported. 7. Related work There has been only a little work on specifying the problem domain of patterns. The reason for this may be that the benefits of pattern’s problem domain have not been recognized as much as the solution domain. The most relevant work is the work by Jackson [7]. In his book, he discusses a notion of problem frames which capture a class of simple problems in a broadly defined domain. A problem frame consists of four kinds of elements, a machine domain, problem domains, requirements and interfaces between them. The machine domain is the solution system being built. Problem domains are the problems of interest that the system should solve. They are analogous to domain classes in objectoriented development. Requirements are conditions that must be satisfied when the problems are solved. The concept of problem frames is similar to problem specifications in ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 585 our work in that both capture a family of similar problems. However, problem frames are aimed at providing a conceptual view of a large domain which is sometimes vague, rather than formalizing concrete properties (e.g., structures and collaborations of participants, a participant’s properties) of the domain. Thus, problem frames are highly generic and coarse-grained in order to cover all the problems in the domain. Problem frames are also not necessarily object-oriented, although there is some correspondence with object-oriented concepts. Another relevant work is the work by Lano et al. [8]. In their work, a design pattern is considered as a transformation that consists of a ‘‘before’’ and ‘‘after’’ specification where the before specification can be viewed as a problem specification. The focus of their work is to develop transformations from a ‘‘before’’ specification to a ‘‘after’’ specification at the pattern level without considering a specific application context. Thus, they do not have any notion of pattern conformance. More importantly, it is not described how a before specification can be developed. There has been considerable work done on specifying the solution domain of design patterns. The work can be categorized into formal method-based approaches and UML-based approaches. Some representative work in formal method-based approaches includes the work by Mikkonen [14] and Eden [10]. Mikkonen [14] uses DisCo, a specification method based on the Temporal Logic of Actions to specify the behaviors of patterns. Eden [10] introduces LePUS, a pattern specification language based on higher order monadic logic to specify a pattern’s structural and behavioral properties. These works inspired other researchers (e.g., [9,11–13]) to use the UML in specifying design patterns. Inspired by Eden’s work, Guennec et al. [11] propose a UML-based metamodeling approach in which pattern properties are expressed in terms of meta-collaborations which consist of roles that are played by instances of UML metamodel classes. Their work is somewhat similar to our work with respect to the use of meta roles. However, they do not address the semantics of pattern properties (e.g., pre- and postconditions for behavioral properties, model-level invariants), and interaction behaviors of pattern participants. Lauder and Kent [12] propose an approach to precisely represent patterns using graphical constraint diagrams for UML models. In their work, a pattern is defined at three different layers where the pattern at a lower layer is viewed as a refinement of the one at the layer above. Thus, there is strong traceability between concrete implementations and pattern specifications. Albin-Amiot and Gueheneuc [9] introduce a metamodel expressed in the UML to describe the structural and behavioral aspects of design patterns for automatic code generation and pattern detection in code. The DPML [13] is a visual modeling language that provides a set of modeling constructs (e.g., interface, dimension) to represent the solution of design patterns being used in UML model development. Potentially, these techniques can be used to specify the problem domain of design patterns. However, before they can be used, a rigorous notion of pattern conformance, which is not found in any of the works, should be defined. In our previous work, we proposed the RBML notation to specify the solution domain of design patterns [19–21,27,28], and developed tool support for generating a UML model from an RBML specification [29]. The RBML has been used to specify: (1) the solution domain of twelve design patterns (Abstract Factory, Abstract Method, Singleton, Adapter, Bridge, Composite, Decorator, Interpreter, Iterator, Observer, State, Visitor) from Gamma et al. book [15], and (2) the DAC, MAC and RBAC patterns in the security domain [30], and (3) the checkin–checkout (CICO) pattern in the domain where items are being checked in and checked out [31]. We proposed an approach to evaluating the conformance of a class diagram to a solution SPS of a pattern using the divide-and-conquer paradigm and its tool support ARTICLE IN PRESS 586 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 [25,32]. We proposed techniques for finding pattern instances in a class diagram using a solution SPS of a pattern by representing a class diagram as a logic program and a solution SPS as a query in Prolog, and projecting the logic program to the query [33]. The work presented in this paper continues our previous work. 8. Conclusion We have presented an approach to developing a precise specification of the problem domain of design patterns in a systematic manner. A problem specification can be used as a check-point to evaluate the applicability of the pattern to a problem model. We demonstrated the approach using the Visitor pattern and three problem examples. The following summarizes the findings in this work: While the problem description of the Visitor pattern was helpful to understand the problem context of the pattern, the information on the problem domain in the description was not found to be sufficient to formalize the problem domain. This led to the need of auxiliary pattern resources where we used problem examples in this work for more information about the problem domain. Some properties of the Visitor problem domain could be found only when multiple perspectives of the problem domain were considered. This implies that in order to develop a complete specification, the problem domain should be analyzed from various views. The solution structure of the Composite and Interpreter patterns were found in the problem structure of the Visitor pattern. Similarly, the solution structure of the Mediator pattern was found in the problem structure of the Observer pattern. From these observations, one can reasonably infer that patterns are not only related in their solution domains, but also in problem domains. In the subsequent work, we plan to investigate the complete relationship of patterns including both problem domains and solution domains. The scope of the Visitor problem domain had to be tailored so as to be rigorously specified. This excludes some valid problem models from the problem set characterized by the problem specification. Thus, even if a model is evaluated non conforming to a problem specification, the model should not be blindly considered as an invalid problem model. The proposed approach can be easily adopted for other patterns such as POSA patterns and AGCS patterns. The current version of RBMLCC supports only structural conformance evaluation. However, for a full evaluation the behavioral conformance should also be established. In the next version, we plan to add features for evaluating behavioral conformance of sequence diagrams to IPSs. As an application, the proposed approach can be used in pattern-based model transformations [34] where a problem model is transformed to a solution model using a pattern. An important issue in this field is that not all patterns are applicable to a problem model, and techniques are needed for checking the pattern applicability. The proposed approach can be used to determine applicable patterns. ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 Generalization Role |ProductGeneralization 0..* Classifier Role 1 |Client |Clnt 1..* Association Role |Creates 1..* 587 Realization Role |ProductRealization 0..* |PGeneral |PSupplier |PSpecific |PClient Classifier Role {abstract} |Prod 1..1 |Product |CreateProduct() 1..* Classifier Role 0..* |AbstractProduct Classifier Role 1..* |ConcreteProduct Fig. A1. Problem SPS for the Abstract Factory pattern. Acknowledgments The authors would like to thank Dr. Thomas F. Piatkowski and the anonymous reviewers for their comments to improve the paper. This material is based upon work supported by the National Science Foundation under Grant No. CCF-0523101. Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation. Appendix A. Abstract Factory pattern Fig. A1 shows a problem SPS for the Abstract Factory pattern. The description of the Abstract Factory pattern [3] and six problem examples, two of which are from industry, were used to develop the specification. The examples include a financial tools application, a remote diagnostics application, a display-printer driver, a sports game management system and a car manufacturing application. In the SPS, the Product role hierarchy (see [20] for details of role hierarchies) captures various product structures of problem models. The following shows a constraint template for the CreateProduct role: context jClient :: jCreateProduct( ) Generalization Role |TargetGeneralization 0..* Classifier Role 1 |Client Association Role |Clnt 1..1 |Creates 1..1 Realization Role |TargetRealization 0..* |TGeneral |TSupplier |TSpecific Classifier Role 1..* |TClient {abstract} |Targt 1..1 |Tar 0 |Target Association Role |Uses 0 |Adapt 0 |Request() 1..* Classifier Role 0..* |AbstractTarget Classifier Role 1..* |ConcreteTarget Fig. B1. Problem SPS for the Adapter pattern. Classifier Role 1..* |Adaptee ARTICLE IN PRESS 588 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 post: jClient.jProd ! size( ) ¼ size( )@pre + 1. Appendix B. Adapter pattern Fig. B1 shows a problem SPS for the Adapter pattern. The description of the Adapter pattern [10] and three examples of a vehicle simulation, a drawing application and an array copier were used to developed the specification. In the figure, the role multiplicities on the association role between the Adaptee and the Target role hierarchy and its association end roles are set to 0 which imposes a constraint that there must not be any elements playing the roles. This specifies the motivating problem of the Adapter pattern that adaptee classes cannot be reused in problem models because of their incompatibility. The incompatibility is defined in the OCL as follows: context jAdaptee Inv - - All classes bound to the ConcreteComponent role must be concrete and have an operation - - bound to the CrossCuttingOp role, and the name of the operations must be same. self.allOperations ! forAll(adaptOpj self.jTar.allOperations ! exists(tarOpj Generalization Role |SubjectGeneralization 0..* Realization Role |SubjectRealization 0..* |SSupplier |SGeneral |SSpecific Classifier Role 1..* |SClient {abstract} |Sub 1..1 |Subject Generalization Role |ObserverGeneralization 0..* Association Role |Observes 1..1 Realization Role |ObserverRealization 0..* |OGeneral |SSupplier |SClient |OSpecific Classifier Role 1..* {abstract} |Obsv 1..1 |Observer |SubjectState:|StateType 1..* |ObseverState:|StateType 1..* |SetState(|st:|StateType) 1..* |Update(|s:|Subject) 1..* Classifier Role 0..* |AbstractSubject Classifier Role 1..* |ConcreteSubject Classifier Role 0..* |AbstractObserver |ob1:|Observer |s:|Subject Classifier Role 1..* |ConcreteObserver |ob2:|Observer |SetState(|st:SubjectState) |Notify() repeat i = 1.. NumOfObservers |Update(|s:|Subject) |GetState() Fig. C1. Problem specification for the Observer pattern: (a) observer problem SPS; (b) observer problem IPS. ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 589 tarOp.hasMatchingSignature(adaptOp)) ¼ false). Appendix C. Observer pattern Fig. C1 shows a problem specification including an SPS and IPS for the Observer pattern. The description of the Observer pattern [3] and four examples of an alarm clock, an on-line customer registration, security system and a web-based news service application were used to develop the specification. The SPS in Fig. C1(a) captures various structures of subjects and observers through the jSubject and jObserver role hierarchies. An observation reveals that the SPS structure is quite similar to the solution structure of the Mediator pattern [3], which implies that Mediator solutions are potential problems of the Observer pattern. This corresponds to the description of the Mediator pattern [3], describing that the Observer pattern can be used for communication between colleagues and their mediator. Unlike the Abstract Factory and Adapter patterns whose problem domains are structural, the problem domain of the Observer pattern is behavioral. Fig. C1(b) shows an IPS that captures the behavior observed from the problem examples. The IPS specifies that observers are responsible for notifying other observers for update, which makes themselves highly coupled with each other and consequently reduces their reusability. The following show constraint templates defined for the jGetState, jSetState and jUpdate roles: context jSubject::jSetState(jst:jStateType) - - A SetState operation sets the subject state. post: jSubjectState ¼ jst context jSubject::jGetState( ):jStateType - - A GetState operation returns the current value of SubjectState. post: result ¼ jSubjectState context jObserver::jUpdate(js:jSubject) - - An Update operation changes the value of ObserverState to the value obtained - - from Subject, and invokes a GetState operation call. post: let observerMessage: OclMessage ¼ jSubject^ jGetState( ) ! notEmpty( ) in observerMessage.hasReturned( ) and message.result( ) ¼ st jObserverState ¼ st. The examples used have mostly structural information with little information on behaviors. Only two examples (the alarm clock and on-line customer registration), which were used to develop the IPS, exhibit some information on behaviors. References [1] The Hillside Group Home Page hhttp://hillside.neti. [2] F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad, M. Stal, A System of Patterns: Pattern-Oriented Software Architecture, Wiley, New York, 1996. ARTICLE IN PRESS 590 D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 [3] E. Gamma, R. Helm, R. Johnson, J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, Reading, MA, 1995. [4] M. Grand, Patterns in Java-A Catalog of Reusable Design Patterns Illustrated with UML, Wiley, New York, 1999. [5] W. Pree, Design Patterns for Object-Oriented Software Development, Addison-Wesley, Reading, MA, 1995. [6] D. Schmidt, M. Stal, H. Rohnert, F. Buschmann, Pattern-Oriented Software Architecture: Patterns for Concurrent and Networked Objects, Wiley, New York, 2000. [7] M. Jackson, Problem Frames: Analyzing and Structuring Software Development Problems, Addison-Wesley, Reading, MA, 2001. [8] K. Lano, J. Bicarregui, S. Goldsack, Formalising design patterns, in: Proceedings of the First BCS-FACS Northern Formal Methods Workshop, Electronic Workshops in Computer Science, Springer, Berlin, 1996. [9] H. Albin-Amiot, Y.G. Gueheneuc, 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. [10] A. Eden, Precise specification of design patterns and tool support in their application, Ph.D. Thesis, University of Tel Aviv, Israel, 1999. [11] A.L. Guennec, G. Sunye, J. Jezequel, Precise modeling of design patterns, in: Proceedings of the Third International Conference on the Unified Modeling Language (UML), York, UK, Lecture Notes in Computer Science, vol. 1939, Springer, Berlin, 2000, pp. 482–496. [12] A. Lauder, S. Kent, Precise visual specification of design patterns, in: Proceedings of the 12th European Conference on Object-Oriented Programming, Lecture Notes in Computer Science, vol. 1445, Springer, Berlin, 1998, pp. 114–136. [13] D. Mapelsden, J. Hosking, J. Grundy, Design pattern modelling and instantiation using DPML, in: Proceedings of the 40th International Conference on Technology of Object-Oriented Languages and Systems (TOOLS), ACS, 2002, pp. 3–11. [14] T. Mikkonen, Formalizing design patterns, in: Proceedings of the 20th International Conference on Software Engineering (ICSE), Kyoto, Japan, IEEE Computer Society Press, Silver Spring, MD, 1998, pp. 115–124. [15] D. Kim, A meta-modeling approach to specifying patterns, Ph.D. Thesis, Colorado State University, Fort Collins, CO, 2004. [16] The Object Management Group (OMG), Unified modeling language: superstructure, Version 2.0 Formal/0507-04, OMG, hhttp://www.omg.orgi, August 2005. [17] D.E. DeLano, L. Rising, Patterns for system testing, in: D.R.R. Martin, F. Buschmann (Eds.), Pattern Languages of Program Design, vol. 3, Addison-Wesley, Reading, MA, 1998, pp. 503–527. [18] J. Warmer, A. Kleppe, The Object Constraint Language Second Edition: Getting Your Models Ready for MDA, Addison-Wesley, Reading, MA, 2003. [19] R. France, D. Kim, S. Ghosh, E. Song, A UML-based pattern specification technique, IEEE Transactions on Software Engineering 30 (3) (2004) 193–206. [20] D. Kim, R. France, S. Ghosh, E. Song, A role-based metamodeling approach to specifying design patterns, in: Proceedings of the 27th IEEE Annual International Computer Software and Applications Conference (COMPSAC), Dallas, Texas, IEEE Computer Society Press, Silver Spring, MD, 2003, pp. 452–457. [21] D. Kim, The role-based metamodeling language for specifying design patterns, in: T. Taibi (Ed.), Design Pattern Formalization Technique, Idea Group Inc., 2007. [22] F. Buttner, O. Radfelder, A. Lindow, M. Gogolla, Digging into the Visitor pattern, in: Proceedings of the 16th International Conference on Software Engineering and Knowledge Engineering (SEKE), 2004, pp. 135–141. [23] J. Knudsen, Java 2D Graphics, Oreilly, 1999. [24] B. Eckel, Thinking in Java, second ed., Prentice-Hall, Englewood Cliffs, NJ, 2000. [25] D. Kim, W. Shen, An approach to evaluating structural pattern conformance of UML models, in: Proceedings of the 22nd Annual ACM Symposium on Applied Computing (ACMSAC), Software Engineering Track, Seoul, Korea, March 2007. [26] W. Shen, W.L. Low, Using abstract state machines to support UML model instantiation checking, in: Proceedings of the IASTED International Conference on Software Engineering, Innsbruck, Austria, ACTA Press, 2005, pp. 100–105. ARTICLE IN PRESS D.-K. Kim, C. El Khawand / Journal of Visual Languages and Computing 18 (2007) 560–591 591 [27] R. France, D. Kim, E. Song, S. Ghosh, Using roles to characterize model families, in: H. Kilov (Ed.), Practical Foundations of Business and System Specifications, Kluwer Academic Publishers, Dordrecht, 2003, pp. 179–195. [28] D. Kim, R. France, S. Ghosh, E. Song, Using role-based modeling language (RBML) as precise characterizations of model families, in: Proceedings of the Eighth IEEE International Conference on Engineering of Complex Computer Systems (ICECCS), Greenbelt, MD, IEEE Computer Society Press, Silver Spring, MD, 2002, pp. 107–116. [29] D. Kim, J. Whittle, Generating UML models from pattern specifications, in: Proceedings of the Third ACIS International Conference on Software Engineering Research, Management and Applications (SERA2005), Michigan, USA, IEEE Computer Society Press, Silver Spring, MD, 2005, pp. 166–173. [30] D. Kim, P. Gokhale, A pattern-based technique for developing UML models of access control systems, in: Proceedings of the 30th Annual International Computer Software and Applications Conference (COMPSAC), Chicago, IL, IEEE Computer Society Press, Silver Spring, MD, 2006, pp. 317–324. [31] D. Kim, R. France, S. Ghosh, A UML-based language for specifying domain-specific patterns, Journal of Visual Languages and Computing, Special Issue on Domain Modeling with Visual Languages 15 (3–4) (2004) 265–289. [32] D. Kim, Evaluating conformance of UML modes to design patterns, in: Proceedings of 10th IEEE International Conference on Engineering of Complex Computer Systems (ICECCS), Shanghai, China, IEEE Computer Society Press, Silver Spring, MD, 2005, pp. 30–31. [33] D. Kim, L. Lu, Influence of design pattern instances in UML models via logic programming, in: Proceedings of the 11th IEEE International Conference on Engineering of Complex Computer Systems (ICECCS), Stanford, CA, IEEE Computer Society Press, Silver Spring, MD, 2006, pp. 47–56. [34] R. France, S. Ghosh, E. Song, D. Kim, A metamodeling approach to pattern-based model refactoring, IEEE Software, Special Issue on Model Driven Development 20 (5) (2003) 52–58.