简介
- 在责任链模式中,作为请求接收者的多个对象通过对其后继的引用而连接起来形成一条链。请求在这条链上传递,直到链上某一个接收者处理这个请求。每个接收者都可以选择自行处理请求或是向后继传递请求。
Handler为一个抽象接口【广义概念,并非单纯接口,抽象类、接口】
优点
-
发出请求的客户端并不知道链上的哪一个接收者会处理这个请求,从而实现了客户端和接收者这件的解耦。
-
责任链模式转训OO中的开闭原则
开闭原则:对扩展开放,对变更关闭。
【如果有一个业务变更,则我们希望新增一个类,而非修改一个类】
缺点
- 通过后继传递的方式将会浪费更多的遍历时间
- 创建了大量的对象来表示我们的处理器对象,但是仅仅使用了其中少有的对象,将会对内存带来压力
销售团队的小例子
代码实现
ChainHandler
package com.example.java_study.chain_model.chain;
public abstract class ChainHandler {
//直接后继,用于传递请求
ChainHandler chainHandler;
/**
* 后继set方法
*
* @param chainHandler
*/
public void setChainHandler(ChainHandler chainHandler) {
this.chainHandler = chainHandler;
}
/**
* 折扣方法
*
* @param discountRate 折扣率
*/
public abstract void discount(float discountRate);
}
销售
package com.example.java_study.chain_model.chain;
/**
* 一般销售【允许折扣5%】
*/
public class Sales extends ChainHandler {
@Override
public void discount(float discountRate) {
if (discountRate <= 0.05) {
System.out.println("销售同意了折扣:" + discountRate);
} else {
this.chainHandler.discount(discountRate);
}
}
}
销售经理
package com.example.java_study.chain_model.chain;
/**
* 销售经理【允许折扣10%】
*/
public class Director extends ChainHandler {
@Override
public void discount(float discountRate) {
if (discountRate <= 0.1) {
System.out.println("销售经理同意了折扣:" + discountRate);
} else {
this.chainHandler.discount(discountRate);
}
}
}
老总
package com.example.java_study.chain_model.chain;
/**
* 公司老总【允许折扣15%】
*/
public class Boss extends ChainHandler {
@Override
public void discount(float discountRate) {
if (discountRate <= 0.15) {
System.out.println("公司老总同意了折扣:" + discountRate);
} else {
System.out.println("公司老总拒绝了折扣:" + discountRate);
}
}
}
Handler对象工厂
package com.example.java_study.chain_model.chain_factory;
import com.example.java_study.chain_model.chain.Boss;
import com.example.java_study.chain_model.chain.ChainHandler;
import com.example.java_study.chain_model.chain.Director;
import com.example.java_study.chain_model.chain.Sales;
/**
* ChainHandlerFactory工厂类
*/
public class ChainHandlerFactory {
/**
* ChainHandlerFactory静态工厂方法
*
* @return
*/
public static ChainHandler createChainHandle() {
ChainHandler sales = new Sales();
ChainHandler director = new Director();
ChainHandler boss = new Boss();
sales.setChainHandler(director);
director.setChainHandler(boss);
return sales;
}
}
客户折扣请求处理
package com.example.java_study.chain_model;
import com.example.java_study.chain_model.chain.ChainHandler;
/**
* 客户,折扣请求
*/
public class Customer {
private ChainHandler chainHandler;
public void setChainHandler(ChainHandler chainHandler) {
this.chainHandler = chainHandler;
}
public void requestDiscount(float discountRate) {
this.chainHandler.discount(discountRate);
}
}
Test
package com.example.java_study;
import com.example.java_study.chain_model.Customer;
import com.example.java_study.chain_model.chain_factory.ChainHandlerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Random;
@SpringBootApplication
public class JavaStudyApplication {
public static void main(String[] args) {
Random random = new Random();
Customer customer = new Customer();
customer.setChainHandler(ChainHandlerFactory.createChainHandle());
for (int i = 0; i < 10; i++) {
System.out.println("第" + i + "次请求折扣");
customer.requestDiscount(random.nextFloat());
}
}
}
结果
第0次请求折扣
公司老总拒绝了折扣:0.9828603
第1次请求折扣
公司老总拒绝了折扣:0.5847888
第2次请求折扣
公司老总拒绝了折扣:0.51042056
第3次请求折扣
公司老总拒绝了折扣:0.8946647
第4次请求折扣
销售同意了折扣:0.012163401
第5次请求折扣
销售同意了折扣:0.03205508
第6次请求折扣
销售经理同意了折扣:0.07881558
第7次请求折扣
公司老总拒绝了折扣:0.32865483
第8次请求折扣
公司老总拒绝了折扣:0.3825733
第9次请求折扣
公司老总拒绝了折扣:0.33962655
责任链模式的应用
- spring全局异常处理机制
- 发生异常可向上抛出异常
- JavaScript中的事件模型
- 事件捕获节点延着Document一直向下传递
- 冒泡阶段延着事件元素一直向上传递
- 中间可选择传递或处理
- Web开发中的Filter过滤器