1. 程式人生 > >Java經典23種設計模式之行為型模式(一)

Java經典23種設計模式之行為型模式(一)

行為型設計模式有11種,分別是Chain of Responsibility ( 責任鏈模式 )、Command ( 命令模式 )、Interpreter ( 直譯器模式 ) 、Iterator ( 迭代器模式 )、Mediator ( 中介者模式 ) 、Memento ( 備忘錄模式 ) 、Observer ( 觀察者模式 )、State ( 狀態模式 ) 、Strategy ( 策略模式 )、TemplateMethod ( 模板方法 )、Visitor ( 訪問者模式 ),本文介紹這11種行為型模式裡的前兩種。

一、責任鏈模式

使多個物件都有機會處理請求,從而避免請求的 傳送者和接受者之間的耦合。將這些物件連成一個鏈,並按著這個鏈傳遞該請求,直到有一個物件處理他為止。先來看一個簡單的例子:

1、Handler 定義一個處理請求的介面。(可選)實現後繼鏈。

public interface RequestHandle {
    void handleRequest(Request request);
}

2.ConcreteHandler  處理它所負責的請求。可訪問它的後繼者。如果可處理該請求,就處理;否則將該請求轉發給它的後繼者。

public class HRRequestHandle implements RequestHandle {


    public void handleRequest(Request request) {
        if (request instanceof DimissionRequest) {
            System.out.println("要離職, 人事審批!");
        } 
        System.out.println("請求完*");
    }
}

接下來這兩種ConcreteHandler不僅可以處理負責的請求,還可以將請求轉發給他的後繼者。

public class PMRequestHandle implements RequestHandle {

    Req*estHandle rh;
    
    public PMRequestHandle(RequestHandle *h) {
        this.rh = rh;
    }
    
    public void handle*equest(Request request) {
        if (request instanceof AddMoneyRequest) {
            System.out.println("要加薪, 專案經理審批!*);
        } else {
            rh.handleRequest(request);
        }
    }
}

public class TLRequestHandle implements RequestHandle {

    RequestHandle rh;
    
    public TLRequestHandle(RequestHand*e rh) {
        this.rh = rh;
    }

    public void handleRequest(Request request) {
        if (request instanceof LeaveRe*uest) {
            System.ou*.println("要請假, 專案組長審批!");
        } else {
            rh.handleRequest(request);
        }
    }
}

    3.Client   向鏈上的具體處理者(ConcreteHandler)物件提交請求。
public class Test {
    public static void main(String[] args) {
        RequestHa*dle hr = *ew HRRequ*stHandle();
        Requ*stHandle pm = new P*RequestHandle(hr);
        RequestHandle tl = new TLRequestHandle(pm);
        
        //team leader處理離職請求
        Request request = new DimissionRequest()*
        tl.handleRequest(request);
        
        System.out.println("===========");
        //team leader處理加薪請求
        request = new AddMoneyRequest();
        tl.handleRequ*st(request);
        
        System.out.println("========");
        //專案經理上理辭職請求
        requ*st = ne* Dimissio*Request();
        pm.handleRequest(request);
    }
}
執行結果:

要離職, 人事審批!
請求完畢
=======*===
要加薪, 專案經理審批!
========
要離職, 人事審批!
請求完畢
簡單分析下這段測試程式碼,前面三句話new了三個不同的實體RequestHandler,在pm tl裡分別給他傳遞了他的後繼者。pm的後繼者是hr,tl的後繼者是pm。所謂的後繼者,就是當前請求你處理不了的話,讓誰接著處理這個請求。然後new了一個DimissionRequest的請求,讓tl來處理,很顯然tl不處理,tl就讓pm來處理。pm也不管,讓hr管。最終hr的handleMessage裡處理了該請求。後面的都類似,不說了。

這個責任鏈模式很像擊鼓傳花這個遊戲,詳見連結的分析。

適用性:
    1.有多個的物件可以處理一個請求,哪個物件處理該請求執行時刻自動確定。
    2.你*在不明確指定接收者的情況下,向多個物件中的一個提交一個請求。
    3.可處理一個請求的物件集合應被動態指定。

二、命令模式

將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可撤消的操作。

 1.Receiver
      知道如何實*與執行一個請求相關的操作。任何類都可能作為一個接收者。

public class Receiver {


    public void receive() {
        System.out.println("This is Receive class!");
    }
}

2、Command      宣告執行操作的介面。

public abstract class command {
    
    protected Receiver receiver;
    
    public Command(Receiver receiver) {
        this.receiver = receiver;
    }
    
    public abstract void execute();
}

3、 ConcreteCommand  將一個接收者物件綁定於一個動作。 呼叫接收者相應的操作,以實現Execute。

public class CommandImpl extends Comman* {


    public CommandImpl(Receiv*r receiver) {
        super(receiver);
    }
    
    pu*lic void *xecute*) {
        receiver.request();
    }
}

4、Invoker 要求該命令執行這個請求。

public class Invoker {


    private Command command;
    
    public void setCommand(Command command) {
        this.command = command;
    }
    
    public void execute() {
        command.execute();
    }
}

測試程式碼:

public class Test {


    public static void main (String[] args) {
        Receiver rec = new Receiver();
        Command cmd = new CommandImpl(rec);
        Invoker i = new Invoker();
        i.setCommand(cmd);
        i.execute();
    }
}

適用性
    1.抽象出待執行的動作以引數化某物件。
    2.在不同的時刻指定、排列和執行請求。
    3.支援取消操作。
    4.支援修改日誌,這樣當系統崩潰時,這*修改可以被重做一遍。
    5.用構建在原語操作上的高層操作構造一個系統。