設計模式:行爲型模式(1)

先來張圖,看看這11中模式的關係:java

第一類:經過父類與子類的關係進行實現。第二類:兩個類之間。第三類:類的狀態。第四類:經過中間類算法

1三、策略模式(strategy)小程序

策略模式定義了一系列算法,並將每一個算法封裝起來,使他們能夠相互替換,且算法的變化不會影響到使用算法的客戶。須要設計一個接口,爲一系列實現類提供統一的方法,多個實現類實現該接口,設計一個抽象類(無關緊要,屬於輔助類),提供輔助函數,關係圖以下:設計模式

圖中ICalculator提供統一的方法,
AbstractCalculator是輔助類,提供輔助方法,接下來,依次實現下每一個類:框架

首先統一接口:ide

public interface ICalculator {  
    public int calculate(String exp);  
}  

輔助類:函數

public abstract class AbstractCalculator {  
      
    public int[] split(String exp,String opt){  
        String array[] = exp.split(opt);  
        int arrayInt[] = new int[2];  
        arrayInt[0] = Integer.parseInt(array[0]);  
        arrayInt[1] = Integer.parseInt(array[1]);  
        return arrayInt;  
    }  
}  

三個實現類:測試

public class Plus extends AbstractCalculator implements ICalculator {  
  
    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"\\+");  
        return arrayInt[0]+arrayInt[1];  
    }  
}  

 

public class Minus extends AbstractCalculator implements ICalculator {  
  
    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"-");  
        return arrayInt[0]-arrayInt[1];  
    }  
  
}  

 

public class Multiply extends AbstractCalculator implements ICalculator {  
  
    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"\\*");  
        return arrayInt[0]*arrayInt[1];  
    }  
}  

簡單的測試類:優化

public class StrategyTest {  
  
    public static void main(String[] args) {  
        String exp = "2+8";  
        ICalculator cal = new Plus();  
        int result = cal.calculate(exp);  
        System.out.println(result);  
    }  
}  

輸出:10this

策略模式的決定權在用戶,系統自己提供不一樣算法的實現,新增或者刪除算法,對各類算法作封裝。所以,策略模式多用在算法決策系統中,外部用戶只須要決定用哪一個算法便可。

1四、模板方法模式(Template Method)

解釋一下模板方法模式,就是指:一個抽象類中,有一個主方法,再定義1...n個方法,能夠是抽象的,也能夠是實際的方法,定義一個類,繼承該抽象類,重寫抽象方法,經過調用抽象類,實現對子類的調用,先看個關係圖:

就是在AbstractCalculator類中定義一個主方法calculate,calculate()調用spilt()等,Plus和Minus分別繼承AbstractCalculator類,經過對AbstractCalculator的調用實現對子類的調用,看下面的例子:

public abstract class AbstractCalculator {  
      
    /*主方法,實現對本類其它方法的調用*/  
    public final int calculate(String exp,String opt){  
        int array[] = split(exp,opt);  
        return calculate(array[0],array[1]);  
    }  
      
    /*被子類重寫的方法*/  
    abstract public int calculate(int num1,int num2);  
      
    public int[] split(String exp,String opt){  
        String array[] = exp.split(opt);  
        int arrayInt[] = new int[2];  
        arrayInt[0] = Integer.parseInt(array[0]);  
        arrayInt[1] = Integer.parseInt(array[1]);  
        return arrayInt;  
    }  
}  

 

public class Plus extends AbstractCalculator {  
  
    @Override  
    public int calculate(int num1,int num2) {  
        return num1 + num2;  
    }  
}  

測試類:

public class StrategyTest {  
  
    public static void main(String[] args) {  
        String exp = "8+8";  
        AbstractCalculator cal = new Plus();  
        int result = cal.calculate(exp, "\\+");  
        System.out.println(result);  
    }  
}  

我跟蹤下這個小程序的執行過程:首先將exp和"\\+"作參數,調用AbstractCalculator類裏的calculate(String,String)方法,在calculate(String,String)裏調用同類的split(),以後再調用calculate(int ,int)方法,從這個方法進入到子類中,執行完return num1 + num2後,將值返回到AbstractCalculator類,賦給result,打印出來。正好驗證了咱們開頭的思路。

1五、觀察者模式(Observer)

包括這個模式在內的接下來的四個模式,都是類和類之間的關係,不涉及到繼承,學的時候應該 記得概括,記得本文最開始的那個圖。觀察者模式很好理解,相似於郵件訂閱和RSS訂閱,當咱們瀏覽一些博客或wiki時,常常會看到RSS圖標,就這的意思是,當你訂閱了該文章,若是後續有更新,會及時通知你。其實,簡單來說就一句話:當一個對象變化時,其它依賴該對象的對象都會收到通知,而且隨着變化!對象之間是一種一對多的關係。先來看看關係圖:

我解釋下這些類的做用:MySubject類就是咱們的主對象,Observer1和Observer2是依賴於MySubject的對象,當MySubject變化時,Observer1和Observer2必然變化。AbstractSubject類中定義着須要監控的對象列表,能夠對其進行修改:增長或刪除被監控對象,且當MySubject變化時,負責通知在列表內存在的對象。咱們看實現代碼:

一個Observer接口:

public interface Observer {  
    public void update();  
}  

兩個實現類:

public class Observer1 implements Observer {  
  
    @Override  
    public void update() {  
        System.out.println("observer1 has received!");  
    }  
}  

 

public class Observer2 implements Observer {  
  
    @Override  
    public void update() {  
        System.out.println("observer2 has received!");  
    }  
  
}  

Subject接口及實現類:

 

public interface Subject {  
      
    /*增長觀察者*/  
    public void add(Observer observer);  
      
    /*刪除觀察者*/  
    public void del(Observer observer);  
      
    /*通知全部的觀察者*/  
    public void notifyObservers();  
      
    /*自身的操做*/  
    public void operation();  
}  

 

public abstract class AbstractSubject implements Subject {  
  
    private Vector<Observer> vector = new Vector<Observer>();  
    @Override  
    public void add(Observer observer) {  
        vector.add(observer);  
    }  
  
    @Override  
    public void del(Observer observer) {  
        vector.remove(observer);  
    }  
  
    @Override  
    public void notifyObservers() {  
        Enumeration<Observer> enumo = vector.elements();  
        while(enumo.hasMoreElements()){  
            enumo.nextElement().update();  
        }  
    }  
}  

 

public class MySubject extends AbstractSubject {  
  
    @Override  
    public void operation() {  
        System.out.println("update self!");  
        notifyObservers();  
    }  
  
}  


測試類:

public class ObserverTest {  
  
    public static void main(String[] args) {  
        Subject sub = new MySubject();  
        sub.add(new Observer1());  
        sub.add(new Observer2());  
          
        sub.operation();  
    }  
  
}  

輸出:

update self!
observer1 has received!
observer2 has received!

1六、迭代子模式(Iterator)

顧名思義,迭代器模式就是順序訪問彙集中的對象,通常來講,集合中很是常見,若是對集合類比較熟悉的話,理解本模式會十分輕鬆。這句話包含兩層意思:一是須要遍歷的對象,即彙集對象,二是迭代器對象,用於對彙集對象進行遍歷訪問。咱們看下關係圖:

 

這個思路和咱們經常使用的如出一轍,MyCollection中定義了集合的一些操做,MyIterator中定義了一系列迭代操做,且持有Collection實例,咱們來看看實現代碼:

兩個接口:

public interface Collection {  
      
    public Iterator iterator();  
      
    /*取得集合元素*/  
    public Object get(int i);  
      
    /*取得集合大小*/  
    public int size();  
}  

 

public interface Iterator {  
    //前移  
    public Object previous();  
      
    //後移  
    public Object next();  
    public boolean hasNext();  
      
    //取得第一個元素  
    public Object first();  
}  

兩個實現:

public class MyCollection implements Collection {  
  
    public String string[] = {"A","B","C","D","E"};  
    @Override  
    public Iterator iterator() {  
        return new MyIterator(this);  
    }  
  
    @Override  
    public Object get(int i) {  
        return string[i];  
    }  
  
    @Override  
    public int size() {  
        return string.length;  
    }  
}  

 

public class MyIterator implements Iterator {  
  
    private Collection collection;  
    private int pos = -1;  
      
    public MyIterator(Collection collection){  
        this.collection = collection;  
    }  
      
    @Override  
    public Object previous() {  
        if(pos > 0){  
            pos--;  
        }  
        return collection.get(pos);  
    }  
  
    @Override  
    public Object next() {  
        if(pos<collection.size()-1){  
            pos++;  
        }  
        return collection.get(pos);  
    }  
  
    @Override  
    public boolean hasNext() {  
        if(pos<collection.size()-1){  
            return true;  
        }else{  
            return false;  
        }  
    }  
  
    @Override  
    public Object first() {  
        pos = 0;  
        return collection.get(pos);  
    }  
  
}  

測試類:

public class Test {  
  
    public static void main(String[] args) {  
        Collection collection = new MyCollection();  
        Iterator it = collection.iterator();  
          
        while(it.hasNext()){  
            System.out.println(it.next());  
        }  
    }  
}  

 

輸出:A B C D E

此處咱們貌似模擬了一個集合類的過程,感受是否是很爽?其實JDK中各個類也都是這些基本的東西,加一些設計模式,再加一些優化放到一塊兒的,只要咱們把這些東西學會了,掌握好了,咱們也能夠寫出本身的集合類,甚至框架!

1七、責任鏈模式(Chain of Responsibility)
接下來咱們將要談談責任鏈模式,有多個對象,每一個對象持有對下一個對象的引用,這樣就會造成一條鏈,請求在這條鏈上傳遞,直到某一對象決定處理該請求。可是發出者並不清楚到底最終那個對象會處理該請求,因此,責任鏈模式能夠實現,在隱瞞客戶端的狀況下,對系統進行動態的調整。先看看關係圖:

 

 

Abstracthandler類提供了get和set方法,方便MyHandle類設置和修改引用對象,MyHandle類是核心,實例化後生成一系列相互持有的對象,構成一條鏈。

public interface Handler {  
    public void operator();  
}  

 

public abstract class AbstractHandler {  
      
    private Handler handler;  
  
    public Handler getHandler() {  
        return handler;  
    }  
  
    public void setHandler(Handler handler) {  
        this.handler = handler;  
    }  
      
}  

 

public class MyHandler extends AbstractHandler implements Handler {  
  
    private String name;  
  
    public MyHandler(String name) {  
        this.name = name;  
    }  
  
    @Override  
    public void operator() {  
        System.out.println(name+"deal!");  
        if(getHandler()!=null){  
            getHandler().operator();  
        }  
    }  
}  

 

public class Test {  
  
    public static void main(String[] args) {  
        MyHandler h1 = new MyHandler("h1");  
        MyHandler h2 = new MyHandler("h2");  
        MyHandler h3 = new MyHandler("h3");  
  
        h1.setHandler(h2);  
        h2.setHandler(h3);  
  
        h1.operator();  
    }  
}  

輸出:

h1deal!
h2deal!
h3deal!

此處強調一點就是,連接上的請求能夠是一條鏈,能夠是一個樹,還能夠是一個環,模式自己不約束這個,須要咱們本身去實現,同時,在一個時刻,命令只容許由一個對象傳給另外一個對象,而不容許傳給多個對象。

 1八、命令模式(Command)

命令模式很好理解,舉個例子,司令員下令讓士兵去幹件事情,從整個事情的角度來考慮,司令員的做用是,發出口令,口令通過傳遞,傳到了士兵耳朵裏,士兵去執行。這個過程好在,三者相互解耦,任何一方都不用去依賴其餘人,只須要作好本身的事兒就行,司令員要的是結果,不會去關注到底士兵是怎麼實現的。咱們看看關係圖:

Invoker是調用者(司令員),Receiver是被調用者(士兵),MyCommand是命令,實現了Command接口,持有接收對象,看實現代碼:

public interface Command {  
    public void exe();  
}  

 

public class MyCommand implements Command {  
  
    private Receiver receiver;  
      
    public MyCommand(Receiver receiver) {  
        this.receiver = receiver;  
    }  
  
    @Override  
    public void exe() {  
        receiver.action();  
    }  
}  

 

public class Receiver {  
    public void action(){  
        System.out.println("command received!");  
    }  
}  

 

public class Invoker {  
      
    private Command command;  
      
    public Invoker(Command command) {  
        this.command = command;  
    }  
  
    public void action(){  
        command.exe();  
    }  
} 

 

public class Test {  
  
    public static void main(String[] args) {  
        Receiver receiver = new Receiver();  
        Command cmd = new MyCommand(receiver);  
        Invoker invoker = new Invoker(cmd);  
        invoker.action();  
    }  
}  

輸出:command received!

這個很哈理解,命令模式的目的就是達到命令的發出者和執行者之間解耦,實現請求和執行分開,熟悉Struts的同窗應該知道,Struts其實就是一種將請求和呈現分離的技術,其中必然涉及命令模式的思想!

 

代碼:

http://download.csdn.net/detail/meryhuang/9696706

相關文章
相關標籤/搜索