設計模式第七講-責任鏈模式

小宇渣渣渣發表於2019-03-03

簡介

責任鏈模式的定義:使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之間的耦合關係

將這個物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理他為止。

圖例

責任鏈-根據事情大小來決定責任向上冒泡到誰身上

設計模式第七講-責任鏈模式

場景設定

如上圖-DBA某人把線上資料庫刪了

不好的程式碼實現

package responsibility;

/**
 * 事故類
 */
public class Accident {

    //緊急程度
    private int fireLevel = 0;

    public Accident(int fireLevel) {
        this.fireLevel = fireLevel;
    }

    /**
     * 事件處理
     */
    public void fire() {

        if (this.fireLevel < 2) {
            System.out.println("運維組長處理了");
        } else if (this.fireLevel < 5) {
            System.out.println("CTO處理了");
        } else {
            System.out.println("BOSS處理了");
        }

    }

}
複製程式碼

呼叫(傳入事件等級):

Accident accident = new Accident(3);
accident.fire();
複製程式碼

output:

CTO處理了
複製程式碼

使用責任鏈模式

首先設定下請求物件(方便呼叫傳參):

package responsibility;

public class Request {

    private String requestMsg;

    private Integer requestLevel;

    public Request(String requestMsg, int requestLevel) {
        this.requestMsg = requestMsg;
        this.requestLevel = requestLevel;
    }

    public String getRequestMsg() {
        return this.requestMsg;
    }

    public Integer getRequestLevel() {
        return this.requestLevel;
    }

}
複製程式碼

設定基類handler

package responsibility;

public abstract class Handler {

    /**
     * 管理者名字
     */
    protected String name;

    /**
     * 管理者物件
     */
    protected Handler superior;


    public Handler(String name) {
        this.name = name;
    }

    //設定管理者上級
    public void SetHandler(Handler superior) {

        this.superior = superior;
    }

    //緊急請求
    abstract public void Fire(Request request);
}
複製程式碼

運維組長職能類

package responsibility;

public class OperationLeader extends Handler {

    public OperationLeader(String name) {
        super(name);
    }

    /**
     * 運維組長處理
     *
     * @param request
     */
    public void Fire(Request request) {
        if (request.getRequestLevel() < 2) {
            System.out.println(this.name + "處理了" + request.getRequestMsg());
        } else {
            if (this.superior != null) {
                this.superior.Fire(request);
            }
        }

    }
}
複製程式碼

CTO類

package responsibility;

public class CtoLeader extends Handler {

    public CtoLeader(String name) {
        super(name);
    }

    /**
     * CTO處理
     *
     * @param request
     */
    public void Fire(Request request) {
        if (request.getRequestLevel() < 5) {
            System.out.println(this.name + "處理了" + request.getRequestMsg());
        } else {
            if (this.superior != null) {
                this.superior.Fire(request);
            }
        }

    }
}
複製程式碼

大boss類

package responsibility;

public class Boss extends Handler {

    public Boss(String name) {
        super(name);
    }

    /**
     * CTO處理
     *
     * @param request
     */
    public void Fire(Request request) {

        System.out.println(this.name + "處理了" + request.getRequestMsg());

    }
}

複製程式碼

呼叫:

Request request = new Request("xx資料庫被刪了", 3);

        OperationLeader operationLeader = new OperationLeader("運維組長");
        CtoLeader ctoLeader = new CtoLeader("CTO");
        Boss boss = new Boss("野獸");

        //DBA上級
        operationLeader.SetHandler(ctoLeader);
        //運維組長上級
        ctoLeader.SetHandler(boss);
        //boss兜底

        //最先收到事故的為運維組長
        operationLeader.Fire(request);
複製程式碼

output:

Request request = new Request("xx資料庫被刪了", 3);

OperationLeader operationLeader = new OperationLeader("運維組長");
CtoLeader ctoLeader = new CtoLeader("CTO");
Boss boss = new Boss("野獸");

//DBA上級
operationLeader.SetHandler(ctoLeader);
//運維組長上級
ctoLeader.SetHandler(boss);
//boss兜底

//DBA最先報警
operationLeader.Fire(request);
複製程式碼

UML類圖

設計模式第七講-責任鏈模式

總結

優點:

  • 將請求的傳送者和接受者解耦
  • 可以簡化你的物件,因為它不需要知道鏈的結構
  • 通過改變鏈內的成員和次序,允許你動態的新增和刪除責任

缺點:

  • 物件變得多了,相應物件管理比較複雜
  • 一個請求有可能末端都得不到處理,或者因為沒有正確配置沒有處理

更多精彩內容,歡迎關注熱心的小宇公眾號 (呆呆熊一點通):

設計模式第七講-責任鏈模式

相關文章