目錄
- 第一章 責任鏈模式介紹
- 第二章 責任鏈模式實作
- 2.1、抽象處理者
- 2.2、具體處理者
- 2.3、最終測驗類
- 第三章 責任鏈模式應用
專案地址:https://gitee.com/caochenlei/design-pattern
第一章 責任鏈模式介紹
責任鏈模式的介紹:
在現實生活中,一個事件需要經過多個物件處理是很常見的場景,例如,采購審批流程、請假流程等,公司員工請假,可批假的領導有部門負責人、副總經理、總經理等,但每個領導能批準的天數不同,員工必須根據需要請假的天數去找不同的領導簽名,也就是說員工必須記住每個領導的姓名、電話和地址等資訊,這無疑增加了難度,
責任鏈模式(Chain of Responsibility Pattern)為請求創建了一個接收者物件的鏈,這種模式給予請求的型別,對請求的發送者和接收者進行解耦,這種型別的設計模式屬于行為型模式,在這種模式中,通常每個接收者都包含對另一個接收者的參考,如果一個物件不能處理該請求,那么它會把相同的請求傳給下一個接收者,依此類推,
責任鏈模式的優點:
- 降低了物件之間的耦合度,該模式使得一個物件無須知道到底是哪一個物件處理其請求以及鏈的結構,發送者和接收者也無須擁有對方的明確資訊,
- 增強了系統的可擴展性,可以根據需要增加新的請求處理類,滿足開閉原則,
- 增強了給物件指派職責的靈活性,當作業流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者洗掉責任,
- 責任鏈簡化了物件之間的連接,每個物件只需保持一個指向其后繼者的參考,不需保持其他所有處理者的參考,這避免了使用眾多的 if 或者 if···else 陳述句,
- 責任分擔,每個類只需要處理自己該處理的作業,不該處理的傳遞給下一個物件完成,明確各類的責任范圍,符合類的單一職責原則,
責任鏈模式的缺點:
- 不能保證每個請求一定被處理,由于一個請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理,
- 對比較長的職責鏈,請求的處理可能涉及多個處理物件,系統性能將受到一定影響,
- 職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的復雜性,可能會由于職責鏈的錯誤設定而導致系統出錯,如可能會造成回圈呼叫,
責任鏈模式的場景:
- 多個物件可以處理一個請求,但具體由哪個物件處理該請求在運行時自動確定,
- 可動態指定一組物件處理請求,或添加新的處理者,
- 需要在不明確指定請求處理者的情況下,向多個處理者中的一個提交請求,
責任鏈模式的角色:
- 抽象處理者(Handler)角色:定義一個處理請求的介面,包含抽象處理方法和一個后繼連接,
- 具體處理者(Concrete Handler)角色:實作抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的后繼者,
- 客戶類(Client)角色:創建處理鏈,并向鏈頭的具體處理者物件提交請求,它不關心處理細節和請求的傳遞程序,


第二章 責任鏈模式實作
采購員采購教學器材,請設計程式完成采購審批專案,
-
- 如果金額小于等于 5000,由主任審批 (0<=x<=5000)
-
- 如果金額小于等于 10000,由院長審批(5000<x<=10000)
-
- 如果金額小于等于 30000,由副校長審批(10000<x<=30000)
-
- 如果金額超過 30000 以上,有校長審批(30000<x)
2.1、抽象處理者
Approver
public abstract class Approver {
protected Approver approver;
protected String name;
public Approver(String name) {
this.name = name;
}
public Approver getNext() {
return approver;
}
public void setNext(Approver approver) {
this.approver = approver;
}
public abstract void handleRequest(PurchaseRequest purchaseRequest);
}
2.2、具體處理者
DepartmentApprover
//主任審批
public class DepartmentApprover extends Approver {
public DepartmentApprover(String name) {
super(name);
}
@Override
public void handleRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() < 0 && purchaseRequest.getPrice() <= 5000) {
System.out.println("本次采購請求被 " + this.name + " 處理");
} else {
if (this.approver != null) {
approver.handleRequest(purchaseRequest);
}
}
}
}
DeanApprover
//院長審批
public class DeanApprover extends Approver {
public DeanApprover(String name) {
super(name);
}
@Override
public void handleRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() < 5000 && purchaseRequest.getPrice() <= 10000) {
System.out.println("本次采購請求被 " + this.name + " 處理");
} else {
if (this.approver != null) {
approver.handleRequest(purchaseRequest);
}
}
}
}
ViceSchoolMasterApprover
//副校長審批
public class ViceSchoolMasterApprover extends Approver {
public ViceSchoolMasterApprover(String name) {
super(name);
}
@Override
public void handleRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() < 10000 && purchaseRequest.getPrice() <= 30000) {
System.out.println("本次采購請求被 " + this.name + " 處理");
} else {
if (this.approver != null) {
approver.handleRequest(purchaseRequest);
}
}
}
}
SchoolMasterApprover
//校長審批
public class SchoolMasterApprover extends Approver {
public SchoolMasterApprover(String name) {
super(name);
}
@Override
public void handleRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() > 30000) {
System.out.println("本次采購請求被 " + this.name + " 處理");
} else {
if (this.approver != null) {
approver.handleRequest(purchaseRequest);
}
}
}
}
2.3、最終測驗類
Client
public class Client {
public static void main(String[] args) {
//創建一個請求
PurchaseRequest purchaseRequest = new PurchaseRequest(31000);
//創建審批人員
DepartmentApprover departmentApprover = new DepartmentApprover("張主任");
DeanApprover deanApprover = new DeanApprover("李院長");
ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");
SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("趙校長");
//設定審批鏈
departmentApprover.setNext(deanApprover);
deanApprover.setNext(viceSchoolMasterApprover);
viceSchoolMasterApprover.setNext(schoolMasterApprover);
//開始處理請求
departmentApprover.handleRequest(purchaseRequest);
}
}
本次采購請求被 趙校長 處理
第三章 責任鏈模式應用
在Java中,Servlet容器是責任鏈模式的經典應用,如在tomcat的包中,帶有Filter、FilterChain結尾的類都是使用的是責任鏈模式,
javax.servlet.Filter類使用的就是責任鏈模式來實作對請求的過濾,執行任一請求到資源過濾任務,原始碼如下:
public interface Filter {
public default void init(FilterConfig filterConfig)
throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
public default void destroy() {}
}
javax.Servlet.FilterChain類也是通過責任鏈模式來進行過濾鏈中過濾器的呼叫,原始碼如下:
public interface FilterChain {
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException;
}
FilterChain是Servlet容器提供給開發人員的物件,它提供了對資源的已過濾請求的呼叫鏈的視圖,過濾器使用FilterChain呼叫鏈中的下一個過濾器,或者呼叫過濾器是鏈中的最后一個過濾器,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/275460.html
標籤:java
上一篇:Java基礎語法(八)——與條件控制陳述句再續前緣之switch陳述句
下一篇:Java執行緒池七個引數詳解:核心執行緒數、最大執行緒數、空閑執行緒存活時間、時間單位、作業佇列、執行緒工廠、拒絕策略
