目录
将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
以上定义来自《设计模式之美》
多条件流程判断:权限控制
ERP 系统流程审批:总经理、人事经理、项目经理
Java 过滤器的底层实现 Filter
游戏一共 3 个关卡
进入第二关需要第一关的游戏得分大于等于 70
进入第三关需要第二关的游戏得分大于等于 90
思考:每个关卡中都有下一关的成员变量,并且是不一样的,那么我们可以在关卡上抽象出一个父类或者接口,然后每个具体的关卡去继承或者实现。
抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
抽象类:
- /**
- * 责任链模式--抽象处理者角色
- *
- */
- public abstract class AbstractHandler {
- /**
- * 下一关用当前抽象类来接收
- */
- protected AbstractHandler next;
-
- public void setNext(AbstractHandler next) {
- this.next = next;
- }
-
- public abstract int handler();
- }
链条上的各节点:
- // 编写具体的处理器来继承AbstractHandler类
- public class FirstPassHandler extends AbstractHandler {
- private int play() {
- return 80;
- }
-
- @Override
- public int handler() {
- System.out.println("第一关: FirstPassHandler.handler()");
- int score = play();
- if (score >= 70) {
- // 有下一关
- if (this.next != null) {
- return this.next.handler();
- }
- }
- return score;
- }
- }
-
-
-
- public class SecondPassHandler extends AbstractHandler {
- private int play() {
- return 90;
- }
-
- @Override
- public int handler() {
- System.out.println("第二关: SecondPassHandler.handler()");
-
- int score = play();
- if (score >= 90) {
- // 有下一关
- if (this.next != null) {
- return this.next.handler();
- }
- }
- return score;
- }
- }
-
-
-
- public class ThirdPassHandler extends AbstractHandler {
- private int play() {
- return 95;
- }
-
- @Override
- public int handler() {
- System.out.println("第三关: ThirdPassHandler.handler()");
- int score = play();
- if (score >= 95) {
- // 有下一关
- if (this.next != null) {
- return this.next.handler();
- }
- }
- return score;
- }
- }
客户端处理:
- public class ChainHandlerClient {
- public static void main(String[] args) {
- // 第一关
- FirstPassHandler firstPassHandler = new FirstPassHandler();
- // 第二关
- SecondPassHandler secondPassHandler = new SecondPassHandler();
- // 第三关
- ThirdPassHandler thirdPassHandler = new ThirdPassHandler();
-
- firstPassHandler.setNext(secondPassHandler);
- secondPassHandler.setNext(thirdPassHandler);
-
- // 从第一个关卡开始
- firstPassHandler.handler();
- }
- }
运行结果:

框架中的这种思想,应用于真实业务中时就对应一些修改
举一个例子:
订单详情页中有很多模块,比如:地址模块、商品详情模块...
- @Data
- public class ItemInfo {
- private Long itemId;
- private String itemName;
- }
-
-
- @Data
- public class SkuInfo {
- private Long skuId;
- private String skuName;
- }
- // 抽象方法
- public abstract class AbstractDataHandler<T> {
- protected abstract T doRequest(String query);
- }
- // 实现类
- @Component
- public class AddressInfoHandler extends AbstractDataHandler<ItemInfo> {
-
- @Override
- protected ItemInfo doRequest(String query) {
- ItemInfo info = new ItemInfo();
- info.setItemId(898989L);
- info.setItemName("测试商品");
- return info;
- }
- }
-
- @Component
- public class SkuInfoHandler extends AbstractDataHandler<SkuInfo> {
- @Override
- protected SkuInfo doRequest(String query) {
- SkuInfo info = new SkuInfo();
- info.setSkuId(12121212L);
- info.setSkuName("测试SKU");
- return info;
- }
- }
- // 测试类
- @RestController
- public class ChainController {
- @Autowired
- private SkuInfoHandler skuInfoHandler;
- @Autowired
- private AddressInfoHandler itemInfoHandler;
-
- @RequestMapping("/query")
- public Map convertItemDetail() {
- Map result = new HashMap();
- result.put("skuInfoHandler", skuInfoHandler.doRequest("模拟数据请求"));
- result.put("itemInfoHandler", itemInfoHandler.doRequest("模拟数据请求"));
- System.out.println(JSON.toJSONString(result));
- return result;
- }
- }
执行结果:
- {
- "skuInfoHandler":{
- "skuId":12121212,
- "skuName":"测试SKU"
- },
- "itemInfoHandler":{
- "itemId":898989,
- "itemName":"测试商品"
- }
- }
大家应该看出这其中的不一样了,这个例子中,我们并没有将handler向下传递,而是通过convertItemDetail方法将各模块封装起来,组成一个map返回。
实际开发中,我们要根据不同业务场景将某些设计模式做适配。