责任链模式

Posted chenshouchang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了责任链模式相关的知识,希望对你有一定的参考价值。

概要

最近在写代码的时候,遇到if else 特别多,还存在嵌套情况;这导致代码很长,看着很难受,一点面向对象的感觉都没了;

也使得代码耦合度非常高;

小编通过责任链模式来解决这问题;

责任链模式定义(Chain of Responsibility)

在 GOF 23 中是这么描述的

Avoid coupling the sender of a request to its receiver by giving more then one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

译:通过为多个对象提供处理请求的机会,避免将请求的发送者耦合到其接收者。 链接接收对象并沿链传递请求,直到对象处理它。(总结:为请求创建了一个接收者对象的链。)

 

在这种模式中,小编个人认为有点像Node对象,只是Node里面这里逻辑判断;即请求传递给一个Node,Node不满足处理请求的条件,那么它会把相同请求传递给下一个Node,以此类推递归下去;

具体例子

例子就以我在工作中遇到的问题来阐述吧;

场景描述

往区块链发送交易修改合约时,合约会抛出一个事件,并把合约名称返回;这时中间件负责同步区块链中的交易数据,并根据合约名称来处理不同的合约数据解析转换成合约业务数据;

基本输入: 合约名称(contractName)、消息队列(blockingQueue)、http请求对象(bcClient)

过程: 根据不同合约名称,处理不同合约业务逻辑

输出: 将结果推送到队列中

coding
// 未优化前
if(CONTRACT.RECORD.equals(contractName)){
    System.out.println("process contract record. 使用bcClient 发送RECORD请求,并将结果推到BlockingQueue");
}else if(CONTRACT.RECORD_NTSC.equals(contractName)){
    System.out.println("process contract record_ntsc. 使用bcClient 发送RECORD_NTSC请求,并将结果推到BlockingQueue");
}else if(CONTRACT.REGISTRY.equals(contractName)){
    System.out.println("process contract registry.使用bcClient 发送REGISTRY请求,并将结果推到BlockingQueue.");
}else if(CONTRACT.REGISTRY_NTSC.equals(contractName)){
    System.out.println("process contract registry_ntsc.使用bcClient 发送REGISTRY_NTSC请求,并将结果推到BlockingQueue.");
}else if(CONTRACT.ACCOUNT.equals(contractName)){
    System.out.println("process contract account. 使用bcClient 发送ACCOUNT请求,并将结果推到BlockingQueue");
}else {
    System.out.println("process contract default. 使用bcClient 发送default请求,并将结果推到BlockingQueue.");
}

刚刚毕业的同学或许会觉得这个,这样的代码很正常不过了,但是随着业务的发展if判断可能会越来越长,非常过程过;耦合程度很高; 然后我们再仔细分析代码发现,这种方式就跟链一样一个接一个;

责任链UML设计

技术分享图片

 

 

coding
// 使用责任链模式优化后

public AbstractContract getChainOfContract(){
    
    AbstractContract recordContract = new RecordContract();
    AbstractContract recordNTSCContract = new RecordNTSCContract();
    AbstractContract registryContract = new RegistryContract();
    AbstractContract registryNTSCContract = new RegistryNTSCContract();
    AbstractContract accountContract = new AccountContract();
    AbstractContract decaultContract = new DefaultContract();
    
    recordContract.setNext(recordNTSCContract);
    recordNTSCContract.setNext(registryContract);
    registryContract.setNext(registryNTSCContract);
    registryNTSCContract.setNext(accountContract);
    accountContract.setNext(decaultContract);
    return accountContract;
}

public static void main(String[] args){
    String contractName = args[0];
    AbstractContract contract = getChainOfContract();
    contract.exectue(contractName);
}

这样一写是不是很清晰了;

以上是关于责任链模式的主要内容,如果未能解决你的问题,请参考以下文章

JS设计模式责任链设计模式的代码示例

设计模式----责任链模式

责任链模式

(十五)责任链模式-代码实现

设计模式之责任链模式

责任链模式