责任链模式
⼀个请求沿着⼀条“链”传递,直到该“链”上的某个处理者处理它为⽌。 ⼀个请求可以被多个处理者处理或处理者未明确指定时。 责任链模式⾮常简单异常好理解,相信我它⽐单例模式还简单易懂,其应 ⽤也⼏乎⽆所不在,甚⾄可以这么说,从你敲代码的第⼀天起你就不知不觉 ⽤过了它最原始的裸体结构: switch-case 语句。
应⽤场景
当程序需要使⽤不同⽅式处理不同种类请求, ⽽且请求类型和顺序预 先未知时, 可以使⽤责任链模式。该模式能将多个处理者连接成⼀条 链。 接收到请求后, 它会 “
询问
”
每个处理者是否能够对其进⾏处理。 这样所有处理者都有机会来处理请求。
当必须按顺序执⾏多个处理者时, 可以使⽤该模式。 ⽆论你以何种顺 序将处理者连接成⼀条链, 所有请求都会严格按照顺序通过链上的处 理者。
代码:
1. 基础抽象类
/**
* 价格处理人, 负责处理客户的责任申请
* @author WHM
*/
public abstract class PriceHandler {
/**
* 直接后继, 用于处理请求
*/
protected PriceHandler successor;
public void setSuccessor(PriceHandler successor) {
this.successor = successor;
}
/**
* 处理折扣申请
*/
public abstract void processDiscount(float discount);
}
2. 申请链对象
/**
* 导购员
* @author WHM
*/
public class Director extends PriceHandler {
@Override
public void processDiscount(float discount) {
if (discount <= 0.35) {
System.out.format("%s 销售员申请价: %.2f%n", this.getClass().getName(), discount);
} else {
successor.processDiscount(discount);
}
}
}
3 第一层
/**
* 组长折扣
* @author WHM
*/
public class Lead extends PriceHandler {
public void processDiscount(float discount) {
if (discount <= 0.15) {
System.out.format("%s 组长申请价: %.2f%n", this.getClass().getName(), discount);
} else {
successor.processDiscount(discount);
}
}
}
4 第二层
/**
* 经理折扣
* @author WHM
*/
public class Manager extends PriceHandler {
public void processDiscount(float discount) {
if (discount <= 0.2) {
System.out.format("%s 经理申请价: %.2f%n", this.getClass().getName(), discount);
} else {
successor.processDiscount(discount);
}
}
}
5 第三层
/**
* ceo折扣
*
* @author WHM
*/
public class Ceo extends PriceHandler {
public void processDiscount(float discount) {
if (discount <= 0.55) {
System.out.format("%s 执行官申请价: %.2f%n", this.getClass().getName(), discount);
} else {
System.out.format("%s 执行官申请不到: %.2f%n", this.getClass().getName(), discount);
}
}
}
6 生成责任链
/**
* 生成责任链
* @author WHM
*/
public class PriceHandlerFactory {
/**
* 获取PriceHandler 对象
* @return PriceHandler
*/
public static PriceHandler createPriceHandler() {
PriceHandler director = new Director();
PriceHandler lead = new Lead();
PriceHandler manager = new Manager();
PriceHandler ceo = new Ceo();
director.setSuccessor(lead);
lead.setSuccessor(manager);
manager.setSuccessor(ceo);
return director;
}
}
7. 验证类
/**
* 客户买房申请折扣
* @author WHM
*/
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 random = new Random();
for (int i = 0; i < 10; i++) {
System.out.print((i + 1) + "号顾客:");
customer.requestDiscount(random.nextFloat());
}
}
}
8 结果:
总结:
if else嵌套比较多的情况,可以考虑是否合适。
- 解耦合
- 符合开闭原则
- 顺序组合执行
- 源码应用: Servlet.FilterChainr的doFilter SpringSecurity