A Declarative Evolution Framework for Object-Oriented Design Patterns

Object-oriented design patterns and high-level refactorings are popular means of implementing and evolving large object-oriented software systems. Unfortunately, these techniques are inadequately supported at implementation level by current-day
of 10
All materials on our website are shared by users. If you have any questions about copyright issues, please report us to resolve them. We are always happy to assist you.
Related Documents
  A Declarative Evolution Framework for Object-Oriented Design Patterns Tom Mens and Tom Tourw´eProgramming Technology LabVrije Universiteit BrusselPleinlaan 2 - 1050 Brussel - Belgium   tom.mens, tom.tourwe  Abstract Object-oriented design patterns and high-level refac-torings are popular means of implementing and evolv-ing large object-oriented software systems. Unfortunately,these techniques are inadequately supported at implemen-tation level by current-day software development environ-ments. To alleviate this problem, we propose to use the promising technique of declarative metaprogramming. It offers a tight, yet flexible, symbiosis between a base lan-guage and a metalevel declarative reasoning engine. It  provides a uniform and language-independentway to spec-ify design patterns and transformations declaratively, to in-stantiate patterns and generate code for them, and to dealwiththeevolutionofthese patterninstances. Providingsup- portforevolutionofasoftware system interms ofthe design pattern instances it uses is the main emphasis of this paper. 1. Introduction  Design patterns are a popular and successful means of implementing flexible and reusable software systems [7],and can be regarded as coarse-grained building blocks of object-oriented design. Unfortunately, they have to be en-coded manually into applications because current-day soft-ware development environments lack explicit support fordesign patterns. This gives rise to a number of problems. If developersareacquaintedwithdesignpatterns,butunfamil-iar with the software, they can spend a considerableamountof time finding out which patterns are used and where [1].Secondly, even if developers are aware of the patterns thatare used in the software, they do not necessarily know alltheir implications. Nothing prohibits developers from mak-ing changes to the code that break the constraints imposedby some pattern instance. Finally, pattern instances are of-ten combined and interact with others to achieve certain be-haviour. As suchinteractionsareimplicit, theycanbeeasilyforgottenby the programmer,potentially resulting in incon-sistent code.All these problems can be tackled by explicitly repre-senting design pattern instances [12], as well as their evolu-tion. This helps the developerto better understandthe code,and allows him to reason about the software and its evolu-tion at a higherlevel of abstraction. While we couldemployany high-level description of the software [14] as a basisfor our approach, we selected design patterns for severalreasons: they are generally applicable, well-documented,well-understood and commonly used. Furthermore, theyform an excellent means for documenting and communi-cating the design of a software system [9]. To deal withsoftware evolution at a high level, we propose to use refac-toring transformations [16] that automate many commondesigntransitionsandreducethe likelihoodoferrors. Whilesuch transformations have been shown to support the intro-duction of design pattern instances in object-orientedappli-cations [17, 19], we are not aware of their usage to supportthe evolution of design pattern instances. Providing suchsupport in an intuitive and seamless way will be the maincontribution of this paper. To this extent, we will use thetechnique of  declarative metaprogramming . 2. Declarative metaprogramming 2.1. Context Declarative metaprogramming is currently being inves-tigated as a technique to support state-of-the-art softwaredevelopment. It is based on a tight symbiosis between anobject-oriented base language and a declarative metalan-guage. This makes it possible to reason about and to ma-nipulate object-oriented programs in a straightforward andintuitive way [21]. The technique has already been usedto check and enforce programming conventions and best-practice patterns [14], to detect design pattern instances inexisting source code [20], to specify and reason about de-sign patterns [8], and to check conformance of a software  implementation to its intended architecture [13].In this paper, we use the technique to support the evo-lution of a software system in terms of the design patterninstances it uses. The approach we propose involves a va-riety of useful activies with design patterns: specification (to describe design patterns, their instances and their con-straints), generation (to generate skeleton code for patterninstancesbased onthe specifications),andmost importantly transformation (to specify refactoring transformations thatcan be applied to a given design pattern instance) and evo-lution (to detect and resolve conflicts during evolution of apattern instance). 2.2. Syntax Allexperimentsreportedoninthispaperwereconductedusing SOUL, a logic programming language implementedon top of the object-oriented language Smalltalk [20, 21].SOUL is a variant of Prolog [4] with some minor syntacticdifferences. Below we give an example of the syntax. Likein Prolog, lines starting with % indicate comments, a commadenotes a logical conjuction, and :- separates the head andbody of a logic rule. The main difference with Prolog isthat logic variables are always preceded by a question mark (e.g., ?P, ?C, ?D ) because atoms are allowed to begin withan uppercase letter. % two examples of logic facts: ×ÙÐ××  ´  ÏØÙØØÓÒ  µ   ×ÙÐ××  ´  ÙØØÓÒÅÙØØÓÒ  µ    % two examples of logic rules: ÖÖÝ  ´  È      µ  :- ×ÙÐ××  ´  È      µ   ÖÖÝ  ´  È      µ  :- ×ÙÐ××  ´  È      µ  ÖÖÝ  ´        µ    Logic queries can be used to trigger the above logicclauses. For example, the query hierarchy(Widget,?C) de-termines whether a descendant of class Widget exists, andretrieves the result in the variable ?C (in this case there aretwo solutions ?C=Button and ?C=MacButton ). The query hi-erarchy(Widget,MacButton) checks whether the class MacBut-ton is a (possibly indirect) descendant of  Widget , and returnstrue. 2.3. Language Symbiosis Inordertobeabletoreasonaboutandmanipulateobject-oriented source code, we need a way to access this codefrom within the declarative metalanguage SOUL. To thisextent, all object-oriented language constructs (such as in-heritance relationships and instance variables) are reifiedas facts in the metalanguage by the representational map- ping predicates. This is achieved by hardcodingthem in themetalevel interface. Table 1 lists those mapping predicatesthat are needed for the purpose of this paper. The represen-tational mapping predicates are largely independent of theparticular object-oriented base-language that is used, sincethey cover concepts that are present in one way or anotherin most object-oriented languages.Typically, representational mapping predicates are usedlike ordinary logic predicates (i.e., for checking and re-trieving information). Alternatively, they can also be usedto generate source code. For each representational map-pingpredicate,a generateCode predicateis definedthathard-codes the appropriate implementation in the meta-level in-terface. For example, the predicate generateCode(subclass-(Widget,Button)) creates new classes Widget and Button inthe source code (if they do not already exist) and connectsthem via an inheritance relationship.Other predicates can be defined in terms of the repre-sentational mapping predicates. For example, the followingclause specifies how code should be generated for the hier-archy predicate (in terms of the code-generation facility forthe subclass predicate): ÒÖØÓ  ´  ÖÖÝ  ´  È      µµ  :- ÒÓÒÚÖ  ´  È  µ  ÒÓÒÚÖ  ´    µ   ÒÖØÓ  ´  ×ÙÐ××  ´  È      µµ    3. Specification This section shows how to specify design patterns, theirconstraints and their instances in a declarative way. We as-sume a basic familiarity with design patterns as introducedin the book of Gamma et al. [7]. Note that we will onlyfocus on the structure (and part of the behaviour) of a de-sign pattern. Other properties (such as intent, motivation,consequences and so on) are not considered, since they aremuch harder to capture in a declarative formalism and arenot strictly needed for our purposes. 3.1. Specifiying design patterns and their instances Design patterns are declarativelyspecified using the pat-tern predicatethatspecifies thekindofpattern(e.g., compos-ite, visitor, abstractFactory ) and a set of required roles(correspondingto the participantsof the pattern). Below wespecify the roles for the abstractFactory pattern (as listedin [7]) that will be used as a running example throughoutthis paper: ÔØØÖÒ  ´  ×ØÖØØÓÖÝ    ×ØÖØØÓÖÝÓÒÖØØÓÖÝÒÖÈÖÓÙØ ×ØÖØÈÖÓÙØÓÒÖØÈÖÓÙØ×ØÖØÊÐØÓÒ ÓÒÖØÊÐØÓÒ×ØÖØØÓÖÝÅØÓ ÓÒÖØØÓÖÝÅØÓ  µ    An instanceofa designpatternis determinedbya uniqueidentifier, the kind of pattern, and a set of concrete partici-pants attached to each role in the pattern.  Representational Mapping Predicate Description class(?C) C must be a class subclass(?P,?C) class C must be a direct subclass of class PconcreteSubclass(?P,?C) class C must be a concrete subclass of class PabstractMethod(?C, ?M) M must be an abstract method of class CconcreteMethod(?C, ?M, ?B) M must be a concrete method with body B in class CclassMethod(?C, ?M, ?B) M must be a class method with body B in class CinstanceVariable(?C, ?V) V must be an instance variable of class CobjectCreationBody(?M, ?B, ?C) body B of method M must create an instance of  C Table 1. Representational Mapping Predicates MSLook  newWindownewButton MacLook  newWindownewButton Look  newWindow newButton  Widget Window Button  MSWindowMacWindowMacButtonMSButton Figure 1. Instance AF1 of the abstractFactory pattern As a concrete example, have a look at the design of Fig-ure 1 that represents part of a user-interface builder. It con-tains a number of  Widget s, like Window and Button , and anumber of  Look s, like MSLook and MacLook . Each concretelook creates its own particular widgets, using factory meth-ods such as newWindow and newButton . (object creation is de-noted by dashed lines). The declarative specification of thisinstance AF1 of pattern abstractFactory looks as follows: ÔØØÖÒÁÒ×ØÒ  ´    ½  ×ØÖØØÓÖÝ  µ   ÖÓÐ  ´    ½  ×ØÖØØÓÖÝÄÓÓ  µ   ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÅËÄÓÓ  µ   ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÅÄÓÓ  µ   ÖÓÐ  ´    ½  ÒÖÈÖÓÙØÏØ  µ   ÖÓÐ  ´    ½  ×ØÖØÈÖÓÙØÏÒÓÛ  µ   ÖÓÐ  ´    ½  ×ØÖØÈÖÓÙØÙØØÓÒ  µ   ÖÓÐ  ´    ½  ÓÒÖØÈÖÓÙØ    ÅËÏÒÓÛÏÒÓÛ  µ   ÖÓÐ  ´    ½  ÓÒÖØÈÖÓÙØ    ÅËÙØØÓÒÙØØÓÒ  µ   ÖÓÐ  ´    ½  ÓÒÖØÈÖÓÙØ    ÅÏÒÓÛÏÒÓÛ  µ   ÖÓÐ  ´    ½  ÓÒÖØÈÖÓÙØ    ÅÙØØÓÒÙØØÓÒ  µ   ÖÓÐ  ´    ½  ×ØÖØÊÐØÓÒ    ÄÓÓÏÒÓÛ  µ   ÖÓÐ  ´    ½  ×ØÖØÊÐØÓÒ    ÄÓÓÙØØÓÒ  µ   ÖÓÐ  ´    ½  ÓÒÖØÊÐØÓÒ    ÅËÄÓÓÅËÏÒÓÛ  µ   ÖÓÐ  ´    ½  ÓÒÖØÊÐØÓÒ    ÅÄÓÓÅÏÒÓÛ  µ   ÖÓÐ  ´    ½  ÓÒÖØÊÐØÓÒ    ÅËÄÓÓÅËÙØØÓÒ  µ   ÖÓÐ  ´    ½  ÓÒÖØÊÐØÓÒ    ÅÄÓÓÅÙØØÓÒ  µ   ÖÓÐ  ´    ½  ×ØÖØØÓÖÝÅØÓ    ÒÛÏÒÓÛÄÓÓÏÒÓÛ  µ   ÖÓÐ  ´    ½  ×ØÖØØÓÖÝÅØÓ    ÒÛÙØØÓÒÄÓÓÙØØÓÒ  µ   ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÅØÓ    ÒÛÏÒÓÛÅËÄÓÓ  µ   ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÅØÓ    ÒÛÏÒÓÛÅÄÓÓ  µ   ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÅØÓ    ÒÛÙØØÓÒÅËÄÓÓ  µ   ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÅØÓ    ÒÛÙØØÓÒÅÄÓÓ  µ    3.2. Specifying design pattern constraints Design patterns impose constraints on the software inwhich they are used. When evolving the software, care hasto be taken that these constraints are not breached. As anexample, the abstractFactory pattern specifies that factorymethods in an abstract factory class must be defined as ab-stract methods, and must be overridden by concrete meth-odsin a concretefactoryclass. Thedeclarativespecificationof these and other constraints, using the predicate pattern-Constraint , is shown below: ÔØØÖÒÓÒ×ØÖÒØ  ´  Á×ØÖØØÓÖÝ  µ  :-       such that ÖÓÐ  ´  Á×ØÖØØÓÖÝ      µ    % there must be exactly one abstract factory ÔØØÖÒÓÒ×ØÖÒØ  ´  Á×ØÖØØÓÖÝ  µ  :-       such that ÖÓÐ  ´  Á×ØÖØØÓÖÝ      µ        such that ÖÓÐ  ´  ÁÓÒÖØØÓÖÝ      µ  ÖÖÝ  ´        µ  % all concrete factories must be descendants of the abstract factory       such that ÓÒÖØËÙÐ××  ´        µ  ÖÓÐ  ´  ÁÓÒÖØØÓÖÝ      µ    % all concrete subclasses of the abstract factory must be concrete factories  ÔØØÖÒÓÒ×ØÖÒØ  ´  Á×ØÖØØÓÖÝ  µ  :-     Å        È    such that ÖÓÐ  ´  Á×ØÖØØÓÖÝÅØÓ    Å        È  µ  ÖÓÐ  ´  Á×ØÖØØÓÖÝ      µ  ×ØÖØÅØÓ  ´      Å  µ   ÖÓÐ  ´  Á×ØÖØÈÖÓÙØ    È  µ          such that ÖÓÐ  ´  ÁÓÒÖØØÓÖÝ      µ  ÖÓÐ  ´  ÁÓÒÖØØÓÖÝÅØÓ    Å      µ    % all abstract factory methods must be defined as abstract methods in an % abstract factory and must be overridden by a concrete factory method in % each concrete factory class ÔØØÖÒÓÒ×ØÖÒØ  ´  Á×ØÖØØÓÖÝ  µ  :-     Å        such that ÖÓÐ  ´  ÁÓÒÖØØÓÖÝÅØÓ    Å      µ  ÖÓÐ  ´  ÁÓÒÖØØÓÖÝ      µ   ÓÒÖØÅØÓ  ´      Å    ÓÝ  µ  % all concrete factory methods must be defined as concrete methods % in a concrete factory         È    such that ÖÓÐ  ´  ÁÓÒÖØÊÐØÓÒ        È  µ  ÓØÖØÓÒÓÝ  ´  Å    ÓÝ    È  µ  % all concrete factory methods must create exactly one concrete product       such that ÖÓÐ  ´  Á×ØÖØØÓÖÝÅØÓ    Å        È  µ  ÖÖÝ  ´        µ  ÖÖÝ  ´  È    È  µ    % all concrete factory methods must override exactly one abstract factory % method In the above and following examples, we use mathemat-ical notation, such as set inclusion ( ¾  ), universal (   ) andexistential (   ) quantifiers, and we use indentation to denotenesting of quantified variables. Note that this is only syn-tactic sugar to enhance the readability of the paper. 3.3. Generating code for pattern instances Pattern instantiation can be achievedvia the software de-velopment environment that asks the developer for the re-quired information, and then triggers a query createPattern with the proper arguments: ÖØÈØØÖÒ  ´    ½  ×ØÖØØÓÖÝ    ×ØÖØØÓÖÝ  ´  ÄÓÓ  µ   ÓÒÖØØÓÖÝ  ´  ÅËÄÓÓÅÄÓÓ  µ   ÒÖÈÖÓÙØ  ´  ÏØ  µ   ×ØÖØÈÖÓÙØ  ´  ÏÒÓÛÙØØÓÒ  µ    µ  The createPattern clause asserts (i.e., adds) logicfacts inthe database by invoking the addRole clause for each role inthe pattern to be instantiated: ÖØÈØØÖÒ  ´  ÁÒ×ØÒ    ÈØØÖÒÃÒ    ÊÓÐËØ  µ  :- ××ÖØ  ´  ÔØØÖÒÁÒ×ØÒ  ´  ÁÒ×ØÒ    ÈØØÖÒÃÒ  µµ        ÊÓÐ  ´  ÈÖØÔÒØ×  µ  ¾    ÊÓÐËØ        È  ¾    ÈÖØÔÒØ×    ÊÓÐ  ´  ÁÒ×ØÒ    ÊÓÐ    È  µ    addRole indirectlygenerates(skeleton)sourcecodebyin-voking the generate predicate: ÊÓÐ  ´  ÁÒ×ØÒ    ÊÓÐ    ÈÖØÔÒØ  µ  :- ××ÖØ  ´  ÖÓÐ  ´  ÁÒ×ØÒ    ÊÓÐ    ÈÖØÔÒØ  µµ   ÒÖØ  ´  ÁÒ×ØÒ    ÊÓÐ    ÈÖØÔÒØ  µ    generate is implemented in terms of the representationalmapping of Table 1. For example, in order to instantiatean abstractFactory pattern, we need to generate code forthe appropriate classes of the abstractFactory , concreteFac-tory, genericProduct, abstractProduct and concreteProduct roles. Furthermore, we need to specify that abstractFacto-ryMethod and concreteFactoryMethod roles are implementedas abstract methods and concrete methods, respectively. ÒÖØ  ´  Á×ØÖØØÓÖÝ      µ  :- ÒÖØÓ  ´  Ð××  ´    µµ   ÒÖØ  ´  ÁÓÒÖØØÓÖÝ      µ  :- ÖÓÐ  ´  Á×ØÖØØÓÖÝ      µ   ÒÖØÓ  ´  ×ÙÐ××  ´        µµ   ÒÖØ  ´  ÁÒÖÈÖÓÙØ    È  µ  :- ÒÖØÓ  ´  Ð××  ´  È  µµ   ÒÖØ  ´  Á×ØÖØÈÖÓÙØ    È  µ  :- ÖÓÐ  ´  ÁÒÖÈÖÓÙØ    È  µ   ÒÖØÓ  ´  ×ÙÐ××  ´  È    È  µµ   ÒÖØ  ´  ÁÓÒÖØÈÖÓÙØ    È    È  µ  :- ÖÓÐ  ´  Á×ØÖØÈÖÓÙØ    È  µ   ÒÖØÓ  ´  ×ÙÐ××  ´  È    È  µµ   ÒÖØ  ´  Á×ØÖØØÓÖÝÅØÓ    ÅØÓ        È  µ  :- ÒÖØÓ  ´  ×ØÖØÅØÓ  ´      ÅØÓ  µµ   ÒÖØ  ´  ÁÓÒÖØØÓÖÝÅØÓ    ÅØÓ      µ  :- ÖÓÐ  ´  Á×ØÖØØÓÖÝÅØÓ    ÅØÓ        È  µ   ÖÓÐ  ´  ÁÓÒÖØÈÖÓÙØ    È    È  µ   ÖÓÐ  ´  ÁÓÒÖØÊÐØÓÒ        È  µ   ÒÖØÇØÖØÓÒÓÝ  ´  ÅØÓ    ÓÝ    È  µ   ÒÖØÓ  ´  ÓÒÖØÅØÓ  ´      ÅØÓ    ÓÝ  µµ    The generateObjectCreationBody predicate generates theappropriate method body for the concrete factory method,based on the name of the method and the name of the con-crete product it needs to instantiate. For example, the fol-lowing Smalltalk code will be generated for the newWindow and newButton methods in the MSLook class: MSLook>>newWindowˆMSWindow new.MSLook>>newButtonˆMSButton new. Note that we use generateObjectCreationBody instead of the generateCode and the objectCreationBody predicate. Thereason is that it relies on the special quoted code block con-struct that is present in SOUL to generate and return a tex-tual representation of the body. This representation is thenused to add the method to the implementation through the generateCode predicate. Since no unification is defined forquoted code blocks, we cannot use the same predicate fortesting and generation purposes. For a detailed descriptionof the process of code generation using quoted code blocks,we refer to [21]. 4. Evolution Transformations The representational mapping predicates of Table 1 canbe combined to form refactoring transformations that makehigh-level structural changes to the software. We can alsospecify design pattern transformations to evolve pattern in-stances. Both kinds of transformations reduce the likeli-hood of introducing programming errors.  4.1. Refactoring transformations We define high-level software transformations as acombination of more primitive transformations by usinglogic rules. For example, the composite transformation extractSuperclass first uses the representational mapping togenerate a new class, and then redirects the parent of allgiven classes to this new superclass via the software trans-formation changeSuperclass , which is defined in a similarway. ÜØÖØËÙÔÖÐ××  ´  Ð×××    ËÙÔÖÐ××  µ  :- ÒÖØÓ  ´  Ð××  ´  ËÙÔÖÐ××  µµ          ¾    Ð×××    ØÖÒ×ÓÖÑ  ´  ÒËÙÔÖÐ××  ´      ËÙÔÖÐ××  µµ    To apply any given transformation rule (such as extractSuperclass ) to the software, the predicate transform is needed. The implementation of  transform looks as fol-lows: ØÖÒ×ÓÖÑ  ´  ÌÖÒ×ÓÖÑØÓÒ  µ  :- ÈÖÓÒØÓÒ  ´  ÌÖÒ×ÓÖÑØÓÒ  µ   ÐР ´  ÌÖÒ×ÓÖÑØÓÒ  µ    These high-level software transformations are similar tothe idea of  refactorings [16, 17], except that we do not re-quire our transformations to be behaviour preserving. Thisis because we want to be able to express any kind of evo-lution of the software, even if this evolution does not pre-serve the srcinal behaviour or structure. Nevertheless, wehave borrowed the idea of  preconditions , which must besatisfied before the transformation can be applied. As wewill see later, preconditions facilitate the detection of evo-lution conflicts. An example of a simple precondition forthe extractSuperclass transformationis given below. It usesthe class predicate to check whether all given classes areeffectively present in the implementation. ÈÖÓÒØÓÒ  ´  ÜØÖØËÙÔÖÐ××  ´  Ð×××    ËÙÔÖ  µµ  :-       ¾    Ð×××    Ð××  ´    µ    4.2. Design pattern transformations  Design pattern transformations are used to manage theevolution of a given pattern instance over time. They di-rectly invoke the predicate addRole to modify the specifica-tion of the pattern instance and its associated source code.For example, the transformation addConcreteFactory , that isused to add a new concrete factory to an abstractFactory pattern instance, is given below: ÓÒÖØØÓÖÝ  ´  ×ØÖØØÓÖÝ    Á      µ  :- ÊÓÐ  ´  ÁÓÒÖØØÓÖÝ      µ        È  such that ÖÓÐ  ´  Á×ØÖØÈÖÓÙØ    È  µ  Ù×ÖÁÒÔÙØ  ´  ’Name of concrete ?AP created byconcrete ?CF =’     È            È  µ    % ask the user for the name of the concrete product ?CP that % should be instantiated by the new concrete factory ÊÓÐ  ´  ÁÓÒÖØÈÖÓÙØ    È    È  µ   ÊÓÐ  ´  ÁÓÒÖØÊÐØÓÒ        È  µ      ÅØÓ  such that ÖÓÐ  ´  Á×ØÖØØÓÖÝÅØÓ    ÅØÓ        È  µ  ÊÓÐ  ´  ÁÓÒÖØØÓÖÝÅØÓ    ÅØÓ      µ    The query transform(addConcreteFactory(abstract-Factory,AF1,LinuxLook)) invokes the transformation addConcreteFactory(abstractFactory,AF1,LinuxLook) , afterhaving verified its preconditions. The query requests andreceives the following user input: Name of concrete Window created by concrete LinuxLook = LinuxWindow Name of concrete Button created by concrete LinuxLook = LinuxButton This information is used to update the specification of the pattern instance AF1 . Only the added pattern roles arementioned below in the order in which they are added: ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÄÒÙÜÄÓÓ  µ   ÖÓÐ  ´    ½  ÓÒÖØÈÖÓÙØ    ÄÒÙÜÏÒÓÛÏÒÓÛ  µ   ÖÓÐ  ´    ½  ÓÒÖØÊÐØÓÒ    ÄÒÙÜÄÓÓÄÒÙÜÏÒÓÛ  µ   ÖÓÐ  ´    ½  ÓÒÖØÈÖÓÙØ    ÄÒÙÜÙØØÓÒÙØØÓÒ  µ   ÖÓÐ  ´    ½  ÓÒÖØÊÐØÓÒ    ÄÒÙÜÄÓÓÄÒÙÜÙØØÓÒ  µ   ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÅØÓ    ÒÛÏÒÓÛÄÒÙÜÄÓÓ  µ   ÖÓÐ  ´    ½  ÓÒÖØØÓÖÝÅØÓ    ÒÛÙØØÓÒÄÒÙÜÄÓÓ  µ    Since addConcreteFactory is defined in terms of  addRole ,and addRole makesuseofthe generate predicate,addingnewparts to the specification immediately generates the corre-sponding code fragments as well. This results in the struc-ture of Figure 2.Many other useful design pattern transformations can bedefined for abstractFactory , as well as for any other designpattern [5]. For example, a removeAbstractProduct transfor-mation can be defined as follows: ÖÑÓÚ×ØÖØÈÖÓÙØ  ´  ×ØÖØØÓÖÝ    Á    È  µ  :- ÖÓÐ  ´  Á×ØÖØØÓÖÝ      µ        È  such that ÖÓÐ  ´  ÁÓÒÖØÈÖÓÙØ    È    È  µ        such that ÖÓÐ  ´  ÁÓÒÖØÊÐØÓÒ        È  µ      Å  such that ÖÓÐ  ´  ÁÓÒÖØØÓÖÝÅØÓ    Å      µ  ÖÑÓÚÊÓÐ  ´  ÁÓÒÖØØÓÖÝÅØÓ    Å      µ   ÖÑÓÚÊÓÐ  ´  Á×ØÖØØÓÖÝÅØÓ    Å        È  µ   ÖÑÓÚÊÓÐ  ´  ÁÓÒÖØÊÐØÓÒ        È  µ   ÖÑÓÚÊÓÐ  ´  Á×ØÖØÊÐØÓÒ        È  µ   ÖÑÓÚÊÓÐ  ´  ÁÓÒÖØÈÖÓÙØ    È    È  µ   ÖÑÓÚÊÓÐ  ´  Á×ØÖØÈÖÓÙØ    È  µ    As can be seen, it is defined in terms of the removeRole predicate,that is responsibleforremovingparticipantsfromthe pattern instance’s description: ÖÑÓÚÊÓÐ  ´  ÁÒ×ØÒ    ÊÓÐ    ÈÖØÔÒØ  µ  :- ÖÑÓÚ  ´  ÁÒ×ØÒ    ÊÓÐ    ÈÖØÔÒØ  µ   ÖØÖØ  ´  ÖÓÐ  ´  ÁÒ×ØÒ    ÊÓÐ    ÈÖØÔÒØ  µµ   
Related Search
We Need Your Support
Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.

Thanks to everyone for your continued support.

No, Thanks