設計模式(9)-責任鏈模式詳解(易懂)

秦子帥發表於2018-02-12

責任鏈模式的定義

責任鏈模式是一種設計模式。在責任鏈模式裡,很多物件由每一個物件對其下家的引用而連線起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個物件決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個物件最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。

模型:

image

  • Hander:抽象處理者

  • ConcreteHander:具體處理者

下面模型程式碼如下:

1.設計等級類


public class Level {
    private  int level=1;

    public  Level(int level){
        this.level=level;
    }

    public int getLevel() {
        return level;
    }
}

複製程式碼

2.請求類


public class MyRequest {

    Level level;
    public  MyRequest(Level level){
        this.level=level;
    }
    public int  getLevel(){

        return level.getLevel();
    }

}

複製程式碼

3.響應類


public class Response {
    private String message;
    public Response(String message) {
        Log.d("qzs","處理完成");
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
}

複製程式碼

4.抽象處理者類


public abstract class AbstractHandler  {
    //判斷下一個處理者是誰
    private AbstractHandler nextHandler = null;

    public final Response handlerRequest(MyRequest request) {
        Response response = null;

        if(this.getHandlerLevel()==request.getLevel()) {
            response = this.response(request);
        }else {
            if(this.nextHandler != null) {
                Log.d("qzs","轉到下一個處理者中...");
                response = this.nextHandler.handlerRequest(request);
            }else {
           Log.d("qzs","後面沒有處理請求了...");
            }
        }
        return response;
    }
    public void setNextHandler(AbstractHandler handler) {
        nextHandler = handler;
    }
    //拿到等級
    protected abstract int getHandlerLevel();
    //響應
    protected abstract Response response(MyRequest request);
}

複製程式碼

5.定義具體的處理者,這裡就定義了兩個:


public class ConcreteHandlerA extends AbstractHandler {
    @Override
    protected int getHandlerLevel() {
        return 0;
    }

    @Override
    protected Response response(MyRequest request) {
        Log.d("qzs","正在處理中“ConcreteHandlerA");
        return new Response("響應處理結果A") ;
    }
}

public class ConcreteHandlerB extends AbstractHandler {
    @Override
    protected int getHandlerLevel() {
        return 1;
    }

    @Override
    protected Response response(MyRequest request) {
        Log.d("qzs","正在處理中“ConcreteHandlerB");
        return new Response("響應處理結果B") ;
    }
}

複製程式碼

6.呼叫:

前提是A到B組成了一個鏈,並且上面A的等級是0,B是1;發出的請求先經過A如果不能處理就交給B:


  AbstractHandler handler1=new ConcreteHandlerA();
        AbstractHandler handler2=new ConcreteHandlerB();
        //A到B組成一個鏈
        handler1.setNextHandler(handler2);
        Response response=handler1.handlerRequest(new MyRequest(new Level(1)));

複製程式碼

上面程式碼我傳送的等級是1,結果應該是由B解決的,下面是執行結果:

image

如果你傳入的等級不在A和B的範圍,執行結果如下:

image

說明沒有適合的了。


例項說明

如果上面的定義不是很明白,下面直接例項說明一下。

例子:家裡的小孩想出去玩,需要請示一下,這裡規定一級請示爸爸,爸爸同意了就可以出去玩了;如果爸爸不在家就請示(二級)媽媽,媽媽同意了也可以出去玩;如果都不在家就不允許出去玩。

1.編寫等級類,響應類,請求類,這些都沒有變化可以直接去上面看就可以了。

2.抽象處理類:


public abstract class AbstractHandler  {
    //判斷下一個處理者是誰
    private AbstractHandler nextHandler = null;

    public final Response handlerRequest(MyRequest request) {
        Response response = null;

        if(this.getHandlerLevel()==request.getLevel()) {
            response = this.response(request);
        }else {
            if(this.nextHandler != null) {
                Log.d("qzs","轉到下一個處理者中...");
                response = this.nextHandler.handlerRequest(request);
            }else {
           Log.d("qzs","爸爸媽媽不在家...");
            }
        }
        return response;
    }
    public void setNextHandler(AbstractHandler handler) {
        nextHandler = handler;
    }
    //拿到等級
    protected abstract int getHandlerLevel();
    //響應
    protected abstract Response response(MyRequest request);
}

複製程式碼

3.具體處理者,也就是爸爸和媽媽:


public class Father extends AbstractHandler {
    @Override
    protected int getHandlerLevel() {
        return 1;
    }

    @Override
    protected Response response(MyRequest request) {
        Log.d("qzs","正在處理中“Father”");
        Log.d("qzs","爸爸同意孩子出去玩了");
        return  new Response("") ;
    }
}

public class Mother extends  AbstractHandler{
    @Override
    protected int getHandlerLevel() {
        return 2;
    }

    @Override
    protected Response response(MyRequest request) {
        Log.d("qzs","正在處理中“Mother”");
        Log.d("qzs","媽媽同意孩子出去玩了");
        return new Response("") ;
    }
}

複製程式碼

4.呼叫

如果傳入的等級1:


      AbstractHandler handler1=new Father();
        AbstractHandler handler2=new Mother();
        //先問爸爸,爸爸不在家再問媽媽
        handler1.setNextHandler(handler2);
        Response response=handler1.handlerRequest(new MyRequest(new Level(1)));

複製程式碼

執行結果:

image

傳入其他的等級也可以,這個大家可以自己去試一試。

責任鏈模式的優缺點及其他

1.優點

  • 耦合度降低,請求和處理是分開的

2.缺點

  • 責任鏈太長或者每條鏈判斷處理的時間太長會影響效能。特別是遞迴迴圈的時候

  • 不一定被處理,每個職責類的職責很明確,這就需要對寫預設的處理了

責任鏈模式重要的兩點:分離職責,動態組合

本文部分定義參考了網上博文和網上資訊...


大家可以關注我的微信公眾號:「安卓乾貨鋪」一個有質量、有態度的公眾號!

設計模式(9)-責任鏈模式詳解(易懂)

相關文章