一.什麼是責任鏈模式
責任鏈模式(Chain of Responsibility)
將接收者對象連成一條鏈,並在該鏈上傳遞請求,直到有一個接收者對象處理它。通過讓更多對象有機會處理請求,避免類請求的發送者和接收者之間的耦合。
二.如何實現責任鏈模式
/**
* Created by John on 2018/11/22.
* 價格處理人,負責處理客戶折扣申請
*/
public abstract class PriceHandler {
//直接後繼處理人,用於傳遞請求
protected PriceHandler successor;
public void setSuccessor(PriceHandler successor) {
this.successor = successor;
}
/**
* 處理折扣申請
* @param discount
*/
public abstract void processDiscount(float discount);
}
/**
* Created by John on 2018/11/22.
* 銷售, 可以批准5%以內的折扣
*/
public class Sales extends PriceHandler {
@Override
public void processDiscount(float discount) {
if (discount <= 0.05){
System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
}else {
successor.processDiscount(discount);
}
}
}
/**
* Created by John on 2018/11/22.
* 銷售小組長, 可以批准15%以內的折扣
*/
public class Lead extends PriceHandler {
@Override
public void processDiscount(float discount) {
if (discount <= 0.15) {
System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), discount);
} else {
successor.processDiscount(discount);
}
}
}
/**
* 銷售經理, 可以批准30%以內的折扣
*/
public class Manager extends PriceHandler {
@Override
public void processDiscount(float discount) {
if(discount<=0.3){
System.out.format("%s批准了折扣:%.2f%n",this.getClass().getName(),discount);
}else{
System.out.format("%s拒絕了折扣:%.2f%n", this.getClass().getName(),discount);
}
}
}
public class PriceHandlerFactory {
/**
* 創建PriceHandler的工廠方法
*/
public static PriceHandler createPriceHandler() {
PriceHandler sales = new Sales();
PriceHandler lead = new Lead();
PriceHandler man = new Manager();
sales.setSuccessor(lead);
lead.setSuccessor(man);
return sales;
}
}
/**
* 客戶,請求折扣
*/
public class Customer {
private PriceHandler priceHandler;
public void setPriceHandler(PriceHandler priceHandler) {
this.priceHandler = priceHandler;
}
public void requestDiscount(float discount) {
priceHandler.processDiscount(discount);
}
public static void main(String[] args) {
Customer customer = new Customer();
customer.setPriceHandler(PriceHandlerFactory.createPriceHandler());
Random rand = new Random();
for (int i = 1; i <= 100; i++) {
System.out.print(i + ":");
customer.requestDiscount(rand.nextFloat());
}
}
}
三.責任鏈模式如何解耦
在責任鏈模式中,作爲請求接收者的多個對象通過對其後繼的引用而連接起來形成一條鏈。請求在這條鏈上傳遞,知道這條鏈上的某一個接收者處理該請求。每個接收者都可以選擇執行處理請求或是向後繼傳遞請求。
發出請求的客戶端並不知道鏈上的哪一個接收者會處理請求,從而實現了客戶端與接收者之間的解耦。
責任鏈模式真的是一個好的方案嗎?
不符合開閉原則:要依據項目的實際情況而定
性能考量
四.責任鏈模式的應用
Java中的異常處理機制
FilterChain並不是一個純粹的責任鏈,在上面的例子的責任鏈中,同一時間只有一個handler處理請求,而在FilterChain中同一時間可以有多個handler處理請求。
SpringSecurity中的Filter Chain。