Recipe 23.2. Applying the Director Design PatternProblemYou want to define a set of roles to be implemented by unknown sets of application classes so they can be interacted with generically by an abstract aspect. SolutionApply the Director aspect-oriented design pattern. Figure 23-2 shows the key components of the Director pattern. Figure 23-2. The structure of the Director patternThe key roles in the Director pattern shown in Figure 23-2 are:
DiscussionThe Director pattern decouples the generic and reusable aspect behavior from the implementation classes of a specific application, allowing the aspect's logic to direct the abstract roles rather than the implementations. Example 23-2 is modified from Recipe 19.1 and shows how the Director pattern can be implemented in AspectJ to specify the Subject and Observer roles along with some default implementation details for the Subject role. Example 23-2. An example of the Director patternpublic abstract aspect ObserverPattern { protected interface Subject { public void addObserver(Observer observer); public void removeObserver(Observer observer); } protected interface Observer { public void notifyOfChange(Subject subject); } private List Subject.observers = new LinkedList( ); public void Subject.addObserver(Observer observer) { this.observers.add(observer); } public void Subject.removeObserver(Observer observer) { this.observers.remove(observer); } private synchronized void Subject.notifyObservers( ) { Iterator iter = this.observers.iterator( ); while (iter.hasNext( )) { ((Observer)iter.next( )).notifyOfChange(this); } } protected abstract pointcut subjectChange(Subject s); after(Subject subject) : subjectChange(subject) { subject.notifyObservers( ); } } Example 23-3, modified from Recipe 19.1, shows how the abstract ObserverPattern aspect uses the Director pattern to apply the Observer and Subject roles to the ConcreteClassA and ConcreteClassB target application classes. Example 23-3. Applying the Director patterns roles to the target application's classespublic aspect ConcreteClassAObserver extends ObserverPattern { declare parents : ConcreteClassB implements Subject; declare parents : ConcreteClassA implements Observer; protected pointcut subjectChange(Subject s) : call(* ConcreteClassB.set*(..)) && target(s); public void ConcreteClassA.notifyOfChange(Subject subject) { this.doSomething( "ConcreteClassA was notified of a change on " + subject); } } Here are the key characteristics of the Director pattern:
The Director pattern is useful in circumstances where you want to:
See AlsoUsing abstract aspects and pointcuts and declaring the inheritance between aspects is covered in Chapter 15; the Director pattern is most prominently used throughout Chapter 17 through Chapter 19 when implementing the traditional object-oriented design patterns using aspect-oriented techniques. |