最愛Java

          書山有路勤為徑,學海無涯苦作舟

          《AspectJ Cookbook》讀書筆記十九: 實現行為型面向對象設計模式

          一.實現觀察者模式
                  觀察者模式允許設計者創建對象之間的依賴關系,使得如果一個對象的狀態發生變化,則通知另一個對象,并且它可能會產生相應的行動。
          package com.aspectj;

          import java.util.List;
          import java.util.LinkedList;
          import java.util.Iterator;

          public 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();
             }

          }


                  ObserverPattern方面把Subject和Observer角色定義為標識符,可以通過繼承子方面把他們應用于特定的類。通過定義這些角色,ObserverPattern方面就會實現一種機制,當主題改變時,通過該機制來通知觀察者。
          package com.aspectj;

          import com.oreilly.aspectjcookbook.oopatterns.ObserverPattern;

          public 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);
             }

          }
              
              ConcreteClassAObserver把Observer接口應用于ConcreteClassA類,以及把Subject接口應用于ConcreteClassB類。這意味著在ConcreteClassB對象上調用修改器時,將會通知被注冊為觀察者的ConcreteClassA對象。在notifyOfChange(Subject)方法中聲明了在發出通知時,將會調用哪些方法的細節,該方法被添加到ConcreteClassA類中。

          二.實現命令模式
                  命令設計模式本身支持把請求封裝成對象。可以依賴于其目的,把單個或多個操作組合進一個請求。一旦構造了請求對象,就可以從發起對象把它作為單獨的實體進行管理。
          package com.aspectj;

          import java.util.WeakHashMap;

          public abstract aspect CommandPattern 
          {
             
          // Define the Command Pattern interfaces
             
             
          // This interface will be fulfilled by all Commands
             public interface Command
             
          {
                
                
          public void executeCommand(CommandReceiver receiver);
                
                
          public boolean isExecutable();
             }

             
             
          //    This interface will be fulfilled by all CommandInvokers
             public interface CommandInvoker
             
          {
             }

             
             
          //    This interface will be fulfilled by all CommandReceivers
             public interface CommandReceiver
             
          {
             }

             
             
          private WeakHashMap mappingInvokerToCommand = new WeakHashMap();
             
             
          public Object setCommand(CommandInvoker invoker, Command command)
             
          {
                
          return mappingInvokerToCommand.put(invoker, command);
             }

             
             
          public Object removeCommand(CommandInvoker invoker)
             
          {
                
          return setCommand(invoker, null);
             }

             
             
          public Command getCommand(CommandInvoker invoker)
             
          {
                
          return (Command) mappingInvokerToCommand.get(invoker);
             }

             
             
          private WeakHashMap mappingCommandToReceiver = new WeakHashMap();
             
             
          public Object setReceiver(Command command, CommandReceiver receiver)
             
          {
                
          return mappingCommandToReceiver.put(command, receiver);
             }

             
             
          public CommandReceiver getReceiver(Command command)
             
          {
                
          return (CommandReceiver) mappingCommandToReceiver.get(command);
             }

             
             
          protected abstract pointcut commandTrigger(CommandInvoker invoker);
             
             after(CommandInvoker invoker) : commandTrigger(invoker)
             
          {
                Command command 
          = getCommand(invoker);
                
          if (command != null)
                
          {
                   CommandReceiver receiver 
          = getReceiver(command);
                   command.executeCommand(receiver);
                }
           else
                
          {
                   
          // Do nothing: This Invoker has no associated command
                }

             }

             
             
          protected pointcut setCommandTrigger(CommandInvoker invoker, Command command);
             
             after(CommandInvoker invoker, Command command) : setCommandTrigger(invoker, command)
             
          {
                
          if (invoker != null)
                   setCommand(invoker, command);
             }

             
             
          protected pointcut removeCommandTrigger(CommandInvoker invoker);
             
             after(CommandInvoker invoker) : removeCommandTrigger(invoker)
             
          {
                
          if (invoker != null)
                   removeCommand(invoker);
             }

             
             
          public boolean Command.isExecutable()
             
          {
                
          return true;
             }

          }


                  CommandPattern抽象方面定義了一些機制,可以通過這些機制來建立CommandInvoker,Command和CommandReceiver的角色,并且讓它們彼此交互。
          package com.aspectj;

          public aspect ConcreteCommand extends CommandPattern 
          {
              declare parents : TimedEvent 
          implements CommandInvoker;
              declare parents : Printer 
          implements CommandReceiver;
              declare parents : VCardPrinter 
          implements CommandReceiver;
              declare parents : BusinessCard 
          implements Command;

              
          public void BusinessCard.executeCommand(CommandReceiver receiver)
              
          {
                  
          if (receiver instanceof Printer)
                  
          {
                      ((Printer) receiver).println(
          this.toString());
                  }
           else
                  
          {
                      ((VCardPrinter) receiver).printVCard(
          this);
                  }

              }


              
          public void executeCommand(CommandReceiver receiver)
              
          {
                  ((Printer) receiver).println(
          "Command triggered on printer receiver");
              }


              
          protected pointcut commandTrigger(CommandInvoker invoker) : call(
                  
          void TimedEvent.timedOut())
                  
          && target(invoker);
          }


          三.實現迭代器模式
                  迭代器模式提供一種機制,通過它將對象集合或聚合的實現與順序訪問集合的機制隔離開。迭代器(或游標)移動對象的聚合移動,從而提供每個對象,同時對聚合的用戶隱藏次序和訪問實現的細節。
          package com.aspectj;

          import java.util.Iterator;

          public abstract aspect IteratorPattern 
          {
             
          public interface Aggregate
             
          {
                
          public Iterator createIterator();
                
                
          public Iterator createReverseIterator();
             }

          }

                  IteratorPattern抽象方面通過定義一個聚合必須實現的接口(這意味著可以迭代任何對象集合),來聲明Aggregate(聚合)角色。這個接口包括兩個操作:創建正常的迭代器或倒迭代器。
          package com.aspectj;

          import java.util.Iterator;

          public aspect EmployeeIteration extends IteratorPattern 
          {
             declare parents : EmployeeCollection 
          implements Aggregate;

             
          public Iterator EmployeeCollection.createIterator()
             
          {
                
          return new EmployeeIterator(thistrue);
             }


             
          public Iterator EmployeeCollection.createReverseIterator()
             
          {
                
          return new EmployeeIterator(thisfalse);
             }

          }


          四.實現調停者模式
                  調停者模式通過在調停者角色中提供單點依賴性,將適合同事角色的潛在大量類彼此隔開。扮演調停者角色的類通過提供一個公共點來控制同事啟動的不同事件,從而把同事類之間的依賴性減至最小。調停者自身會接受事件,然后封裝一個邏輯,用于通知原始事件的合適同事。
          package com.aspectj;

          import java.util.WeakHashMap;

          public abstract aspect MediatorPattern 
          {
             
          protected interface Colleague
             
          {
             }

             
             
          protected interface Mediator
             
          {
             }

             
             
          private WeakHashMap mappingColleagueToMediator = new WeakHashMap();
             
             
          private Mediator getMediator(Colleague colleague)
             
          {
                Mediator mediator 
          =
                   (Mediator) mappingColleagueToMediator.get(colleague);
                
          return mediator;
             }

             
             
          public void setMediator(Colleague c, Mediator m)
             
          {
                mappingColleagueToMediator.put(c, m);
             }

             
             
          protected abstract pointcut change(Colleague c);
             
             after(Colleague c) : change(c)
             
          {
                notifyMediator(c, getMediator(c));
             }

             
             
          protected abstract void notifyMediator(Colleague c, Mediator m);
          }


                  MediatorPattern抽象方面把Colleague和Mediator角色定義為接口,可以通過繼承子方面將其用于應用程序特定的類。這個方面定義了mappingColleagueToMediator查尋,可以使用setMediator(Colleague,Mediator)方法操縱它,將同事對象賦予調停者對象。
                  MediatorPattern方面提供了由于方面實現的change(..)抽象切入點,在同事發生變化時,這個切入點通過調用notifyMediator(Colleague,Mediator)方法來觸發調停者上的通知。
          package com.aspectj;

          public aspect DialogMediator extends MediatorPattern 
          {
             declare parents : ListBox 
          implements Colleague;
             declare parents : EntryField 
          implements Mediator;
             
             
          protected pointcut change(Colleague c) : (
                   execution(
          void ListBox.setSelection(..)) && this(c));
             
             
          protected void notifyMediator(Colleague c, Mediator m)
             
          {
                ListBox listBox 
          = (ListBox) c;
                EntryField entryField 
          = (EntryField) m;
                entryField.setText(listBox.getSelection());
             }

          }


          五.實現責任鏈模式
                  責任鏈模式允許把請求的來源與決定應該使用哪個處理程序來處理請求隔離開,這個處理程序是從潛在的大量針對請求的處理程序中選擇的。代表連角色的類把請求從其來源,沿著處理程序列表,一直導向一個處理程序,它會接受請求并處理它。
          package com.aspectj;

          import java.util.WeakHashMap;

          public abstract aspect ChainOfResponsibilityPattern 
          {
             
          protected interface Handler
             
          {
             }

             
             
          private WeakHashMap successors = new WeakHashMap();
             
             
          protected void receiveRequest(Handler handler, Object request)
             
          {
                
          if (handler.acceptRequest(request))
                
          {
                   handler.handleRequest(request);
                }
           else
                
          {
                   
          // The handler will not accept the request
                   Handler successor = getSuccessor(handler);
                   
          if (successor == null)
                   
          {
                      
          // Last handler in the chain so must deal with the request
                      
          // This is a rudimentary implementation and more complex
                      
          // logic could be applied here or perhaps in the concrete
                      
          // aspects that extend this abstract one
                      handler.handleRequest(request);
                   }
           else
                   
          {
                      
          // Hand the request on to the next successor in the chain
                      receiveRequest(successor, request);
                   }

                }

             }

             
             
          public boolean Handler.acceptRequest(Object request)
             
          {
                
          // The default as defined here is to reject the request
                
          // This is implemented by the application specific
                
          // concrete aspects
                return false;
             }

             
             
          public void Handler.handleRequest(Object request)
             
          {
                
          // A default empty implementation that is overridden
                
          // if required by the application specific concrete aspects
             }

             
             
          protected abstract pointcut eventTrigger(Handler handler, Object request);
             
             after(Handler handler, Object request) : eventTrigger(handler, request)
             
          {
                receiveRequest(handler, request);
             }

             
             
          public void setSuccessor(Handler handler, Handler successor)
             
          {
                successors.put(handler, successor);
             }

             
             
          public Handler getSuccessor(Handler handler)
             
          {
                
          return ((Handler) successors.get(handler));
             }

          }

                  ChainOfResponsibilityPattern抽象方面定義了Handler接口,然后可通過特殊化的子方面將其應用于參與鏈中的特定應用程序內的所有類。方面維護鏈,并詢問將如何通過特定子方面處理請求的細節。
          package com.aspectj;

          public aspect HelpChain extends ChainOfResponsibilityPattern 
          {
             declare parents : PrintButton 
          implements Handler;
             declare parents : PrintDialog 
          implements Handler;
             declare parents : Manager 
          implements Handler;
             
             
          protected pointcut eventTrigger(Handler handler, Object event) : call(
                   
          void PrintButton.doClick(..))
                   
          && target(handler)
                   
          && args(event);
             
             
          // We introduce the attributes purely to give the handlers a means of
             
          // deciding if they have already handled a request or not
             
          // If they have then they are allowed to refuse the request in this
             
          // example.
             
          // In a real application these would not be required.
             private boolean Handler.alreadyHandledRequest = false;
             
             
          public boolean Handler.acceptRequest(Object event)
             
          {
                
          return !this.alreadyHandledRequest;
             }

             
             
          public void PrintButton.handleRequest(Object event)
             
          {
                
          if (!this.acceptRequest(event))
                
          {
                   System.out.println(
                   
          "PrintButton Forced to handle Request due to being last in the chain (Implementation Decision)");
                }

                System.out.println(
          "PrintButton handling request: " + event);
                
          this.alreadyHandledRequest = true;
             }

             
             
          public void PrintDialog.handleRequest(Object event)
             
          {
                
          if (!this.acceptRequest(event))
                
          {
                   System.out.println(
                   
          "PrintDialog Forced to handle Request due to being last in the chain (Implementation Decision)");
                }

                System.out.println(
          "PrintDialog handling request: " + event);
                
          this.alreadyHandledRequest = true;
             }

             
             
          public void Manager.handleRequest(Object event)
             
          {
                
          if (!this.acceptRequest(event))
                
          {
                   System.out.println(
                   
          "Manager Forced to handle Request due to being last in the chain (Implementation Decision)");
                }

                System.out.println(
          "Manager handling request: " + event);
                
                
          this.alreadyHandledRequest = true;
             }

          }



          六.實現備忘錄模式
                  備忘錄模式提供了一種機制,通過這種機制,可以在以后的某個時間恢復對象的原始狀態,而無需把準確的機制與要回滾狀態的對象耦合起來。備忘錄封裝了在以后某個時間恢復對象的先前內部狀態所需的全部信息。這種能力可以用于提供某種形式的撤銷特性,以恢復特定應用程序內對象的狀態。
          package com.aspectj;

          public abstract aspect MementoPattern 
          {
             
          public interface Memento
             
          {
                
          public void setState(Originator originator);
                
          public Object getState();
             }

             
             
          public interface Originator
             
          {
                
          public void setMemento(Memento memento);
                
          public Memento createMemento();
                
          public Object getState();
             }

          }

                  EmployeeMementor指定Employee類是一個發起者,從而支持創建其狀態的備忘錄.createMemento()方法允許客戶獲得Employee對象的備忘錄;setMemento(Memento)方法將把Employee對象恢復到備忘錄中存儲的狀態,當創建備忘錄以訪問和恢復Employee發起者對象時將使用getState()方法。
          package com.aspectj;

          public aspect EmployeeMemento extends MementoPattern 
          {
             declare parents : Employee 
          implements Originator;

             
          public void Employee.setMemento(Memento memento)
             
          {
                Object object 
          = memento.getState();
                Employee stateToRestore 
          = (Employee) object;
                
          this.setName(stateToRestore.getName());
                
          this.setSalary(stateToRestore.getSalary());
             }


             
          public Memento Employee.createMemento()
             
          {
                Memento memento 
          = new DefaultMemento();
                memento.setState(
          this);
                
          return memento;
             }


             
          public Object Employee.getState() throws MementoException
             
          {
                Employee employee 
          = new Employee(this.getName(), this.getSalary());
                
          return employee;
             }

          }




          七.實現策略模式
                  策略模式用于把客戶類和特定算法或策略的實際實現細節隔離開,傳統上,實現策略的所有單獨的類都會實現一個不同的接口,允許把客戶與不同的實現分開。
          package com.aspectj;

          import java.util.Hashtable;

          public abstract aspect StrategyPattern 
          {
             Hashtable strategyPerContext 
          = new Hashtable();
             
             
          protected interface Strategy
             
          {
             }

             
             
          protected interface Context
             
          {
             }

             
             
          public void setConcreteStrategy(Context c, Strategy s)
             
          {
                strategyPerContext.put(c, s);
             }

             
             
          public Strategy getConcreteStrategy(Context c)
             
          {
                
          return (Strategy) strategyPerContext.get(c);
             }

          }


                  StrategyPattern抽象方面將Strategy和Context角色定義為接口。使用一個散列表來查詢要使用的特定的具體策略。
          package com.aspectj;

          public aspect SortingStrategy extends StrategyPattern 
          {
             declare parents : Sorter 
          implements Context;
             declare parents : LinearSorter 
          implements Strategy;
             declare parents : BubbleSorter 
          implements Strategy;
             
             
          int[] around(Sorter s, int[] numbers) : call(int[] Sorter.sort(int[]))
                
          && target(s)
                
          && args(numbers)
             
          {
                Strategy strategy 
          = getConcreteStrategy(s);
                
          if (strategy instanceof BubbleSorter)
                   ((BubbleSorter) strategy).sort(numbers);
                
          else if (strategy instanceof LinearSorter)
                   ((LinearSorter) strategy).sort(numbers);
                
          return numbers;
             }

          }


                  SortingStrategy方面為待排序的特定環境聲明了兩種不同的排序策略。將執行的實際策略依賴與運行時為特定環境聲明的策略類型。
          八.實現訪問者模式
                  訪問者模式封裝了一個請求,當在整個結構中傳遞它時,可以通過對象的層次結構來執行它。
          package com.aspectj;

          public abstract aspect VisitorPattern 
          {
             
          public interface Element
             
          {
                
          public void accept(Visitor visitor);
             }

             
             
          public interface CompositeElement extends Element
             
          {
                
          public Element[] getElements();
             }

             
             
          public interface Result
             
          {
             }

             
             
          public interface Visitor
             
          {
                
          public void visitElement(Element element);
                
                
          public void visitComposite(CompositeElement element);
                
                
          public Result getResult();
             }

             
             
          public void CompositeElement.accept(Visitor visitor)
             
          {
                visitor.visitComposite(
          this);
             }

             
             
          public void Element.accept(Visitor visitor)
             
          {
                visitor.visitElement(
          this);
             }

          }

                  VisitorPattrn抽象方面把CompositeElement和Element角色定義為待訪問的對象結構的一部分。Visitor角色描述了如何通知Visitor它正在訪問哪種元素。這個角色應用于可能傳遞到結構不同部分的對象,他們是復合元素或簡單元素。然后擴展CompositeElement和Element角色,以提供用于傳遞Visitor的方法。
          package com.aspectj;

          public aspect InventoryVisitor extends VisitorPattern 
          {
              declare parents : FloppyDisk 
          implements Element;

              declare parents : HardDisk 
          implements Element;
              
              declare parents : Processor 
          implements Element;

              declare parents : Computer 
          implements CompositeElement;

              declare parents : Motherboard 
          implements CompositeElement;

              declare parents : InventoryReport 
          implements Result;

              
          public Element[] Computer.getElements()
              
          {
                  Element[] elements 
          = new Element[3];
                  elements[
          0= this.getMotherboard();
                  elements[
          1= this.getHardDisk();
                  elements[
          2= this.getFloppyDisk();
                  
          return elements;
              }


              
          public Element[] Motherboard.getElements()
              
          {
                  Element[] elements 
          = new Element[1];
                  elements[
          0= this.getProcessor();
                  
          return elements;
              }


          }


          九.實現模板方法模式
              模板方法模式可以利用它來聲明通用工作流內的抽象方法。
          package com.aspectj;

          public interface AlgorithmDefinition
          {
             
          public String runAlgorithm();

             
          public StringBuffer stepOne();

             
          public void stepTwo(StringBuffer data);

             
          public void stepThree(StringBuffer data);

             
          public String stepFour(StringBuffer data);
          }


          package com.aspectj;

          public aspect DefaultAlgorithmImplementation 
          {    
             
          public String AlgorithmDefinition.runAlgorithm()
             
          {
                StringBuffer dataInProcess 
          = this.stepOne();
                
          this.stepTwo(dataInProcess);
                
          this.stepThree(dataInProcess);
                
          return this.stepFour(dataInProcess);
             }

             
             
          public StringBuffer AlgorithmDefinition.stepOne()
             
          {
                
          return new StringBuffer();
             }

             
             
          public String AlgorithmDefinition.stepFour(StringBuffer data)
             
          {
                
          return data.toString();
             }

          }

                  DefaultAlgorithmImplementation方面指定了算法執行步驟的順序,以及幾個步驟的默認實現。通過使用面向方面技術,可以在接口而不是抽象類中聲明算法模板。然后,依靠靜態橫切技術,可以在具體的方面中指定合適的通用步驟的默認實現,包括以正確順序調用步驟的方法。可以通過實現算法接口的類來完成更特定的步驟,從而在合適的地方自動獲得默認的行為。
                  這種模式的面向方面實現的優點是:它通過把部分抽象實現移到方面中并使用靜態橫切方法來提供默認在接口上的部分實現,消除了模式中的頂級類必須在抽象類中的限制。
          十.實現狀態模式
                  狀態模式提供了一種機制,這種機制,可以基于對象的狀態來改變它的行為。狀態被封裝在它自己的對象中,這個對象然后又被調用對象說包含。調用對象把受其狀態影響的所有方法請求傳遞給狀態對象,狀態對象則基于此刻它的類來改變響應。
          package com.aspectj;

          public aspect TCPConnectionState 
          {
             
          protected TCPState listening = new TCPListen();

             
          protected TCPState acknowledged = new TCPAcknowledged();

             
          protected TCPState closed = new TCPClosed();

             after(TCPConnection connection) : initialization(
          new ())
                
          && target(connection)
             
          {
                listening.setConnection(
          new SocketConnection());
                connection.setState(listening);
             }


             after(TCPConnection connection, TCPState state) : call(
                
          void TCPState +.acknowledge())
                
          && target(state)
                
          && this(connection)
             
          {
                
          if (connection.getState() == listening)
                
          {
                   acknowledged.setConnection(listening.getConnection());
                   connection.setState(acknowledged);
                }

             }


             after(TCPConnection connection, TCPState state) : call(
                
          void TCPState +.close())
                
          && target(state)
                
          && this(connection)
             
          {
                
          if ((connection.getState() == listening)
                   
          || (connection.getState() == acknowledged))
                
          {
                   connection.setState(closed);
                }

             }

          }

                  TCPConnectionState方面指定:TCPConnectionState類狀態將在創建時被偵聽,在調用acknowledge()方法時被確認,以及在調用close()調用時被關閉。它還指定:如果依賴于這些方法的順序調用它們,則會發生什么。無需影響TCPConnection類,既可完成所有這些操作。
          十一.實現外觀模式和解釋器模式
                  上述兩種模式使用面向方面方法無法獲得任何設計或實現上的好處。

          posted on 2008-08-29 10:04 Brian 閱讀(310) 評論(0)  編輯  收藏 所屬分類: 《AspectJ Cookbook》讀書筆記

          公告


          導航

          <2008年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          統計

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          收藏夾

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 河间市| 昭平县| 香港 | 淮阳县| 开平市| 东乡族自治县| 溧水县| 东至县| 黑山县| 庄河市| 会东县| 柘荣县| 桦甸市| 镇原县| 潜江市| 濮阳市| 湖北省| 峡江县| 手机| 如皋市| 宁陕县| 翼城县| 兰考县| 张掖市| 淮北市| 湖南省| 凌云县| 普安县| 景泰县| 宣化县| 长沙市| 菏泽市| 宾阳县| 马山县| 湖北省| 辉南县| 叶城县| 孝昌县| 安阳市| 棋牌| 溆浦县|