碼仔漫畫:做個(gè)審批流程,被領(lǐng)導(dǎo)怒懟“什么玩意兒”!

目錄
故事
責(zé)任鏈簡介
代碼類圖
代碼實(shí)現(xiàn)
責(zé)任鏈優(yōu)缺點(diǎn)
應(yīng)用場景
思維導(dǎo)圖
故事


傳統(tǒng)if-else判斷方式。
public class LeaveApproval {
public static void main(String[] args) {
ExpenseReimbursement maNiuApply = new ExpenseReimbursement();
maNiuApply.setName("Ma Niu");
maNiuApply.setAmount(-100);
if (maNiuApply.getAmount() < 0 ) {
System.out.println("Amount error!");
} else if (maNiuApply.getAmount() <= 500) {
projectManagerHandle(maNiuApply);
} else if (maNiuApply.getAmount() <= 1000) {
departmentManagerHandle(maNiuApply);
}else {
managingDirectorHandle(maNiuApply);
}
}
public static void projectManagerHandle(ExpenseReimbursement expense) {
System.out.println("Project manager approved " + expense.getAmount());
}
public static void departmentManagerHandle(ExpenseReimbursement expense) {
System.out.println("Department manager approved " + expense.getAmount());
}
public static void managingDirectorHandle(ExpenseReimbursement expense) {
System.out.println("Managing director approved " + expense.getAmount());
}
}






簡介
責(zé)任鏈模式(Chain of Responsibility),又名職責(zé)鏈模式,是一種對象行為型模式。定義:為了避免請求發(fā)送者與多個(gè)請求處理者耦合在一起,于是將所有請求的處理者通過前一對象記住其下一個(gè)對象的引用而連成一條鏈;當(dāng)有請求發(fā)生時(shí),可將請求沿著這條鏈傳遞,直到有對象處理它為止。
責(zé)任鏈模式的本質(zhì)是:將請求的發(fā)送者和請求的處理者解耦,讓請求在處理鏈中能進(jìn)行傳遞,由具體的處理者完成處理。
代碼類圖
抽象處理者(Handler):封裝處理請求方法的接口,主要方法有:抽象處理方法和后繼連接節(jié)點(diǎn)。
具體處理者(Concrete Handler):抽象處理者的具體實(shí)現(xiàn)。在抽象處理方法的實(shí)現(xiàn)中,判斷是否處理本次請求。如果能處理就完成請求;如果不能處理就將請求傳遞給鏈上的下一個(gè)處理者。
客戶類(Client):首先,創(chuàng)建各個(gè)具體處理者,并將他們組成處理鏈。之后,將請求提交給鏈頭的具體處理者。
代碼實(shí)現(xiàn)
public class ChainOfResponsibilityPattern {
public static void main(String[] args) {
//組裝責(zé)任鏈
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
handler1.setNext(handler2);
//提交請求
handler1.handleRequest("two");
}
}//抽象處理者角色
abstract class Handler {
private Handler next;
public void setNext(Handler next) {
this.next = next;
}
public Handler getNext() {
return next;
}
//處理請求的方法
public abstract void handleRequest(String request);
}//具體處理者角色1
class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String request) {
if (request.equals("one")) {
System.out.println("ConcreteHandler1 handler!");
} else {
if (getNext() != null) {
getNext().handleRequest(request);
} else {
System.out.println("None handler!");
}
}
}
}//具體處理者角色2
class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String request) {
if (request.equals("two")) {
System.out.println("ConcreteHandler2 handler!");
} else {
if (getNext() != null) {
getNext().handleRequest(request);
} else {
System.out.println("None handler!");
}
}
}
}優(yōu)點(diǎn)
降低了對象之間的耦合度。該模式使得一個(gè)對象無須知道到底是哪一個(gè)對象處理其請求以及鏈的結(jié)構(gòu),發(fā)送者和接收者也無須擁有對方的明確信息。
滿足開閉原則。針對新的需求,可以靈活的增加新的具體處理者,系統(tǒng)可擴(kuò)展性靈活。
增強(qiáng)了給對象指派職責(zé)的靈活性。當(dāng)工作流程發(fā)生變化,可以動態(tài)地改變鏈內(nèi)的成員或者調(diào)動它們的次序,也可動態(tài)地新增或者刪除責(zé)任。
簡化了對象之間的連接。每個(gè)對象只需保持一個(gè)指向其后繼者的引用,避免了使用眾多的 if 或者 if···else 語句。
職責(zé)明確。每個(gè)類只需要處理自己該處理的工作,不該處理的傳遞給下一個(gè)對象完成,符合類的單一職責(zé)原則。
缺點(diǎn)
不能保證每個(gè)請求一定被處理。由于一個(gè)請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理。
對比較長的職責(zé)鏈,請求的處理可能涉及多個(gè)處理對象,系統(tǒng)性能將受到一定影響。
職責(zé)鏈建立的合理性要靠客戶端來保證,增加了客戶端的復(fù)雜性,可能會由于職責(zé)鏈的錯(cuò)誤設(shè)置而導(dǎo)致系統(tǒng)出錯(cuò),還可能會造成循環(huán)調(diào)用。
應(yīng)用場景
多個(gè)對象可以處理一個(gè)請求,但具體由哪個(gè)對象處理該請求在運(yùn)行時(shí)自動確定。
可動態(tài)指定一組對象處理請求,或添加新的處理者。
需要在不明確指定請求處理者的情況下,向多個(gè)處理者中的一個(gè)提交請求。
擴(kuò)展
職責(zé)鏈模式存在以下兩種擴(kuò)展情況:
純的職責(zé)鏈模式:一個(gè)請求必須被某一個(gè)處理者對象所接收,且一個(gè)具體處理者對某個(gè)請求的處理只能采用以下兩種行為之一:自己處理(承擔(dān)責(zé)任);把責(zé)任推給下家處理。
不純的職責(zé)鏈模式:允許出現(xiàn)某一個(gè)具體處理者對象在承擔(dān)了請求的一部分責(zé)任后又將剩余的責(zé)任傳給下家的情況,且一個(gè)請求可以最終不被任何接收端對象所接收。
與裝飾者模式的異同
思維導(dǎo)圖

歡迎關(guān)注微信公眾號:互聯(lián)網(wǎng)全棧架構(gòu),收取更多有價(jià)值的信息。

