Recipe 17.2. Implementing the Prototype PatternProblemYou want to apply the prototype pattern using AspectJ. SolutionThe prototype pattern supports the creation of duplicate objects based on an original object, the prototype. Example 17-3 uses the Director aspect-oriented design pattern (see Chapter 23) to define the generic behavior needed to apply this pattern. Example 17-3. Using an aspect to define the prototype patternpublic abstract aspect PrototypePattern { protected interface Prototype { } public Object Prototype.clone( ) throws CloneNotSupportedException { return super.clone( ); } public Object cloneObject(Prototype object) { try { return object.clone( ); } catch (CloneNotSupportedException ex) { return createCloneFor(object); } } protected Object createCloneFor(Prototype object) { return null; } } DiscussionThe abstract PrototypePattern aspect defines the Prototype interface that can be applied to any class within the target application that is to be a prototype. Those classes are extended with a clone( ) method to support prototype duplication. Figure 17-4 shows the structure of the PrototypePattern abstract aspect with the interfaces and behavior that it defines to support the prototype design pattern. Figure 17-4. The structure of the PrototypePattern abstract aspectA clone( ) method is the Java mechanism for implementing a deep copy of the object. Some base classes may not support being cloned; the PrototypePattern aspect provides the createCloneFor(Prototype) method, so it can be overridden by subaspects to perform specific cloning operations that the generic aspect will not know. Example 17-4 shows how the abstract PrototypePattern aspect can be applied for a specific application. Example 17-4. Applying the abstract PrototypePattern aspect to a target applicationpublic aspect GraphicPrototypes extends PrototypePattern { declare parents : Graphic implements Prototype; declare parents : MusicalNote implements Prototype; declare parents : Staff implements Prototype; protected Object createCloneFor(Prototype object) { if (object instanceof MusicalNote) { return new MusicalNote( ((MusicalNote) object).getX( ), ((MusicalNote) object).getY( )); } else if (object instanceof Staff) { return new Staff(((Staff) object).getX( ), ((Staff) object).getY( )); } else { return null; } } } Figure 17-5 shows an example of the effects that the GraphicsPrototype aspect has on an application's class. Figure 17-5. How the static application structure is affected by the GraphicsPrototype aspectFigure 17-6 shows how the new prototype pattern behavior interacts in an example application. Figure 17-6. Using the new prototype behavior of the Staff classSee AlsoUsing the declare keyword to affect a class hierarchies static structure is explained in more detail in Recipe Recipe 16.2; the Director aspect-oriented design pattern is explained in Recipe 23.3. |