設計模式之責任鏈模式

       做爲一個程序員,咱們的代碼都是進行統一的管理的,一樣會進行一些權限的控制。好比咱們想申請一些非核心代碼,向權限管理員申請下便可。想申請核心代碼的權限,可能權限管理員都沒權利開放,須要項目經理處理。申請支付等關鍵代碼,可能須要技術總監來處理。這樣一個場景使用責任鏈模式來進行處理就能很好地進行。程序員

1、定義

定義(來源:百度百科):責任鏈模式是一種設計模式。在責任鏈模式裏,不少對象由每個對象對其下家的引用而鏈接起來造成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪個對象最終處理這個請求,這使得系統能夠在不影響客戶端的狀況下動態地從新組織和分配責任。
設計模式

重點:bash

一、對請求進行處理的對象鏈成一條處理鏈,如:A持有B引用、B持有C的引用、C持有D的引用,造成一條處理鏈。markdown

二、請求在鏈上傳遞,直到某個對象處理請求。如:A處理不了則讓B處理、B處理不了讓C處理、C處理不了讓D處理ide

2、UML圖

下圖中,咱們定義了抽象類Handler表示處理請求的角色。具體實現有CommonManage 普通管理員,只能處理非核心代碼權限開發。ProjectManage 項目經理,能開放核心代碼權限。ChiefTechnologyOfficer、能開發全部代碼權限,包括支付等核心中的核心。oop


3、實例

代碼實現,爲更好抽象,請求封裝成一個Request對象測試

package com.design.responsibility;

public class Request {

    /**
     *請求code
     * 1表示普通代碼
     * 2表示核心代碼
     * 3表示支付等核心中核心代碼
     */
    public int code;

    public String message;

    public Request(int code, String message){
        this.code = code;
        this.message = message;
    }


    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}複製代碼

抽象處理類this

package com.design.responsibility;

public abstract  class Handler {
    //責任鏈下一節點對象
    Handler nextHandleObj;

    public Handler getNextHandleObj() {
        return nextHandleObj;
    }

    public void setNextHandleObj(Handler nextHandleObj) {
        this.nextHandleObj = nextHandleObj;
    }
    //處理請求的方法
    public abstract void handleRequest(Request request);
}複製代碼

具體的處理類spa

普通管理員,只能開發非核心代碼權限
設計

package com.design.responsibility;
//普通管理員,只能開發非核心代碼權限
public class CommonManage extends Handler {

    @Override
    public void handleRequest(Request request) {
        if(request.getCode() == 1){
            System.out.println("請求:"+request.getMessage()+",普通管理員:已經爲您開放非核心代碼權限!!");
        }else{
            //沒有處理權限,讓責任鏈下一個節點去處理
            super.nextHandleObj.handleRequest(request);
        }
    }

}複製代碼

項目經理,能開放非核心代碼、核心代碼權限

package com.design.responsibility;

public class ProjectManage extends Handler {

    @Override
    public void handleRequest(Request request) {
        if (request.getCode() < 3){
            System.out.println("請求:"+request.getMessage()+",項目經理:已經爲您開放非支付核心代碼權限!!");
        }else {
            //沒有開發支付核心代碼權限,讓責任鏈下一節點去處理
            super.nextHandleObj.handleRequest(request);
        }
    }
}複製代碼

技術總監、能開放全部代碼權限

package com.design.responsibility;

public class ChiefTechnologyOfficer extends Handler {

    @Override
    public void handleRequest(Request request) {
        System.out.println("請求:"+request.getMessage()+",技術總監:已經爲您開放代碼權限!!");
    }

}複製代碼

測試代碼以下

package com.design.responsibility;

public class TestMain {

    public static void main(String[] args) {
        //構建責任鏈  commonManage  -》 projectManage  -》 chiefTechnologyOfficer
        CommonManage commonManage = new CommonManage();
        ProjectManage projectManage = new ProjectManage();
        ChiefTechnologyOfficer chiefTechnologyOfficer = new ChiefTechnologyOfficer();
        commonManage.setNextHandleObj(projectManage);
        projectManage.setNextHandleObj(chiefTechnologyOfficer);
        //申請非核心代碼權限
        Request comCode =new Request(1,"非核心代碼");
        commonManage.handleRequest(comCode);
        //申請核心代碼權限
        Request coreCode =new Request(2,"核心代碼");
        commonManage.handleRequest(coreCode);
        //申請支付代碼權限
        Request payCode =new Request(3,"支付核心代碼");
        commonManage.handleRequest(payCode);

    }
}複製代碼

執行結果


從結果能夠看到,申請不一樣的代碼權限,處理的類是不一樣的,申請非核心代碼,處理類是普通管理員,申請核心代碼,處理類是項目經理,申請支付核心代碼,處理類是技術總監。處理不了的請求就沿着處理鏈往下傳遞請求。

4、總結

從定義中,咱們能夠知道責任鏈模式主要應用在處理請求上。一個請求交予一條責任鏈去處理,責任鏈上能進行處理的類就進行處理,不然繼續沿着責任鏈傳遞請求。

優勢:

一、定義處理類很是靈活,新增處理類,只需新增類並繼承自抽象處理類,增長處處理鏈上便可。

二、責任鏈上處理類處理順序調整靈活。

三、請求發送者跟處理者解耦,發送者只需發送一個請求,並不須要知道責任鏈上哪一個節點處理了請求。

缺點:

一、不能保證責任鏈必定對請求進行了處理。

二、測試相對麻煩,若是編寫錯誤,還可能組成環狀責任鏈,形成代碼死循環。

參考:

《大話設計模式》

相關文章
相關標籤/搜索