这篇记录是今天突然看到别人写的责任链模式文章的时候想起来我在项目中如何应用责任链模式的,因此随手记录下,希望生活更美好。
责任链模式在我们工作中经常接触到的算是Java web中的filter了,每一个HttpRequest都会流经每个filter,在每个filter中对request做感兴趣的事。结构就类似下面这张图。
责任链模式一般由一个抽象类和多个具体实现类组成,示例图如下。
代码演示如下:
① 定义抽象基类
public abstract class Processor {
Processor processor;
public Processor getProcessor() {
return processor;
}
public void setProcessor(Processor processor) {
this.processor = processor;
}
public abstract Object Process(Object request);
}
② 定义具体实现类
// 具体实现类1
public class ProcessorA extends Processor {
@Override
public Object process(Object request) {
if(request.equals("fuhang")){
System.out.println("ProcessorA request process");
}else{
System.out.println("ProcessorA request can not process");
if(processor != null){
processor.process(request);
}
}
return null;
}
}
// 具体实现类2
public class ProcessorB extends Processor {
@Override
public Object process(Object request) {
if(request.equals("fuhang")){
System.out.println("ProcessorB request process");
}else{
System.out.println("ProcessorB request can not process");
if(processor != null){
processor.process(request);
}
}
return null;
}
}
③ 测试类
public class ProcessorTest {
Processor processor;
public Processor getProcessor() {
return processor;
}
public void setProcessor(Processor processor) {
this.processor = processor;
}
public static void main(String[] args) {
// 模拟业务类
ProcessorTest processorTest = new ProcessorTest();
// 手动创建责任链
ProcessorA processorA = new ProcessorA();
ProcessorB processorB = new ProcessorB();
processorA.setProcessor(processorB);
processorTest.setProcessor(processorA);
// 测试
processorTest.getProcessor().process("fuhang");
processorTest.getProcessor().process("zhangsan");
}
}
// 输出
//ProcessorA request process
//ProcessorA request can not process
//ProcessorB request can not process
小结
以上就是一个纯责任链模式的示例程序,从主业务类接收到请求一路向下传递处理,若责任链上某个处理者可以处理请求则结束。
实际开发中大部分使用的是非纯责任链模式,即责任链中每个节点处理完请求后还会继续向下传递,一直到责任链结束,犹如流水线,画个图方便理解。
我是一名Java开发者,但是日常工作是和区块链系统打交道,目前具体来说是和以太坊区块链客户端打交道。
我们有一个需求是监听我们自己智能合约上发生的任何事件,这些事件包括代币转账、黑名单操作、合约拥有者转移、铸币、销毁代币、暂停合约、管理员变更等等事件。在程序中我们需要监听我们自己的智能合约在以太坊公链上发出的事件,事件格式是统一的,当监听到事件时候根据具体事件进行相应处理,有可能需要一个处理器操作,有可能需要多个处理器操作。
从上面的描述我第一印象是工厂的流水线。随后就想设计模式中有没有适用的,最后责任链模式适配我们的需求就再合适不过了。使用责任链模式可以使得代码耦合度降低,各个处理器像链表一样链接起来,互相除了链接关系外耦合度很低。
下面我将我程序demo贴出来做示例(SpringBoot项目):
① TxProcessor(基类)
package com.pinganfu.processor;
import org.web3j.protocol.core.methods.response.Transaction;
public abstract class TxProcessor {
public abstract Object process(Transaction transaction);
}
② TransferTxProcessor(转账交易处理器)
@Component(value="transferTxProcessor")
@Order(value=1)
public class TransferTxProcessor extends TxProcessor{
@Autowired(required=false)
@Qualifier("mintTxProcessor")
private TxProcessor txProcessor;
@Override
public Object process(Transaction transaction) {
System.out.println("TransferTxProcessor transaction process...");
if(txProcessor != null){
return txProcessor.process(transaction);
}
return null;
}
}
③ MintTxProcessor(铸币交易处理器)
@Component(value="mintTxProcessor")
@Order(2)
public class MintTxProcessor extends TxProcessor{
@Autowired(required=false)
@Qualifier(value="claimOwnerShipTxProcessor")
private TxProcessor txProcessor;
@Override
public Object process(Transaction transaction) {
System.out.println("MintTxProcessor transaction process...");
if(txProcessor != null){
return txProcessor.process(transaction);
}
return null;
}
}
④ 测试类MainTest
@Controller
public class MainTest {
@Autowired
@Qualifier(value="transferTxProcessor")
private TxProcessor processor;
@RequestMapping("/test")
public String test(){
Transaction transaction = new Transaction();
processor.process(transaction);
return "fuhang";
}
}
运行程序后控制台输出结果如下:
TransferTxProcessor transaction process...
MintTxProcessor transaction process...
随后我们想在责任链上继续添加处理器只需要创建新的处理器类就ok,这个降低了程序之间的耦合度。
你们的意见或者建议是我成长道路上的推动力