设计模式-责任链模式
Kiml Lv5
  • 前言
    设计模式 - 责任链模式

  • 更新

1
24-09-13 初始记录

简单理解

可以简单的理解为,针对一个请求,做多层处理( 不分先后),并且这些处理可能随着业务需求进行不断变更,这个时候就可以用责任链模式。比如说 Spring 中的 Filter 使用的就是责任链模式。* 这里理解与策略模式的不同在于:责任链有点像 if return 会每个匹配比较,而策略像 map get key 直接匹配一个;责任链多用于解耦,策略多用于封装 *

一般来说,这种多层处理可能代码中使用多个 if 来进行处理。处理方式可以如下:

  1. 将处理的各个流程抽象为各个类(本来 Handler 里边有多个 if方法)

  2. 将多个类用 Chain 链起来,暴露一个方法给 Handler 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface Filter {  
    // 过滤
    void doFilter(String data);
}

class Filter1 implements Filter {
    @Override
    public void doFilter(String data) {
        //doSomething
    }
}

class Filter2 implements Filter {
    @Override
    public void doFilter(String data) {
        //doSomething
    }
}

class Filter3 implements Filter {
    @Override
    public void doFilter(String data) {
        //doSomething
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class FilterChain {  
    List<Filter> filters = new ArrayList<>();

    public FilterChain() {
        filters.add(new Filter1());
        filters.add(new Filter2());
        filters.add(new Filter3());
    }
    
    public void processData(String data) {
        for (Filter filter : filters) {
            filter.doFilter(data);
        }
    }
}
1
2
3
4
5
6
7
8
9
public class Handler {  
    public void handlerRequest(Request request) {
        // 得到请求的数据
        String data = request.getData();
        FilterChain filterChain = new FilterChain();
        // 处理数据
        filterChain.processData(data);
    }
}

通用代码

  1. 业务执行器接口,所有的业务实现都会实现该接口

1
2
3
4
5
6
/**  
 * 业务执行器
 */
public interface BusinessProcess {
    void process(ProcessContext context);
}
  1. 责任链上下文

1
2
3
4
5
6
7
8
9
10
11
/**  
 * 责任链上下文
 */
public class ProcessContext {
    // 标识责任链的code
    private String code;
    // 存储上下文的真正载体
    private Model model;
    // 责任链中断的标识
    private Boolean needBreak = false;
}
  1. 业务执行模板(把责任链的逻辑串起来)

1
2
3
4
5
6
7
8
9
10
11
12
/**  
 * 业务执行模板(把责任链的逻辑串起来)
 */
public class ProcessTemplate {
    private List<BusinessProcess> processList;
    public List<BusinessProcess> getProcessList() {
        return processList;
    }
    public void setProcessList(List<BusinessProcess> processList) {
        this.processList = processList;
    }
}
  1. 责任链的流程控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**  
 * 责任链的流程控制器(整个责任链的执行流程通用控制)
 */
@Data
public class ProcessController {
    
    // 不同的code 对应不同的责任链
    private Map<String, ProcessTemplate> templateConfig = null;

    public void process(ProcessContext context) {
        //根据上下文的Code 执行不同的责任链
        String businessCode = context.getCode();
        ProcessTemplate processTemplate = templateConfig.get(businessCode);
        List<BusinessProcess> actionList = processTemplate.getProcessList();
        //遍历某个责任链的流程节点
        for (BusinessProcess action : actionList) {
            try {
                action.process(context);
                if (context.getNeedBreak()) {
                    break;
                }
            } catch (Exception e2) {
                //...
            }
        }
    }
}
  1. 举例用的两个实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**  
 * 白名单处理器
 */
@Service
public class WhiteListProcess implements BusinessProcess {
    @Override
    public void process(ProcessContext context) {
        UserModel user = (UserModel) context.getModel();
        if ("3y".equals(user.getName())) {
            context.setNeedBreak(true);
        }
    }
}

/**
 * 发消息处理器
 */
@Service
public class SendMessageProcess implements BusinessProcess {

    @Override
    public void process(ProcessContext context) {
        UserModel user = (UserModel) context.getModel();
        System.out.println("给"+user.getName()+"发消息");
    }
}
  1. 把处理器添加到 ProcessTemplate 模板,把 ProcessTemplate 添加到 ProcessControllerMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--发送消息的责任链-->
<bean id="sendMessageTemplate" class="com.chainofresponsibility.ProcessTemplate">
  <property name="processList">
    <list>
      <ref bean="whiteListProcess"></ref>
      <ref bean="sendMessageProcess"></ref>
    </list>
  </property>
</bean>

<!--通用流程处理器,维护多条责任链-->
<bean id="processController" class="com.chainofresponsibility.ProcessController">
  <property name="templateConfig">
    <map>
      <entry key="sendMessage" value-ref="sendMessageTemplate" />
    </map>
  </property>
</bean>
  1. 接口里执行责任链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RestController
public class UserController {
    @Autowired
    private ProcessController processController;

    @RequestMapping("/send")
    public void send(String userName) {
        // 构建上下文
        ProcessContext processContext = new ProcessContext();

        UserModel userModel = new UserModel();
        userModel.setAge("24");
        userModel.setName(userName);
        processContext.setModel(userModel);
        processContext.setCode("sendMessage");
        
        processController.process(processContext);
    }
}

Pipeline

Redis 会用 Pipeline 去做批量的操作。它是「责任链模式」的实现之一。

// 具体分析 todo

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
访客数 访问量