二、13【设计模式】之责任链模式

今天的博客主题

       设计模式 ——》 设计模式之责任链模式


责任链模式(chain of Responsibility Pattern)

 

定义

将链中的每一个节点看作是一个对象,每个节点处理的请求不同,且内部自动维护下一个节点的对象。当一个请求从链式的首端发出时,会沿链的路径依次传递给每一个节点对象,直到有对象处理这个请求为止。

原文解释:使多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

 

就是为请求创建了一个接收者对象的链。

 

使用场景

1)一个请求的处理需要多个对象当中的一个或几个协作处理

2)不明确接收者的情况下,向多个对象中的一个提交一个请求。

3)

在生活中的场景责任链也是比较常见的,比如流程的审批,通关模式的游戏。

 

优点

1)请求与处理解耦

2)控制执行顺序

3)符合开闭原则和单一职责

4)

 

缺点

1)责任链太长或处理时间过长,会影响整体性能。

2)如果节点对象存在循环引用时,会造成死循环,导致系统崩溃

3)

 

源码中的应用

javax.servlet.Filter 
javax.servlet.FilterChain

 

代码示例

责任链模式主要包含两个角色:

抽象处理者(Handler):定义一个请求处理的方法,并维护下一个处理节点 Handler 对象的引用。

具体处理者(ConcreteHandler):对请求的具体处理,如果不关注,则转发。

// 抽象处理对象
abstract class Handler{
    Handler handler;

    public void next(Handler handler) {
        this.handler = handler;
    }

    abstract void doHandler(String request);
}
// 具体处理对象
class ConcreteHandlerA extends Handler{
    @Override
    void doHandler(String request) {
        if(request.contains("A")){
            if(request.indexOf("A") > 0){
                System.out.println("请以A为开始点");
                return;
            }
            System.out.println("包含A,处理完成");
        }else{
            System.out.println("A为必传");
            return;
        }
        handler.doHandler(request);
    }
}

class ConcreteHandlerB extends Handler{
    @Override
    void doHandler(String request) {
        if(request.contains("B")){
            System.out.println("包含B,处理完成");
        }
        handler.doHandler(request);
    }
}

class ConcreteHandlerC extends Handler{
    @Override
    void doHandler(String request) {
        if(request.contains("C")){
            System.out.println("包含C,处理完成");
        }
        // c为最后一个处理对象,不需要设置下一个点
    }
}

// 客户端调用
public class ChainOfResponsibility {
    public static void main(String[] args) {
        Handler ha = new ConcreteHandlerA();
        Handler hb = new ConcreteHandlerB();
        Handler hc = new ConcreteHandlerC();
        // 将定义好的 handler 根据业务串联起来 形成一条链  a-->b-->c
        // 例如审批流程的:组长-->经理-->总监-->CEO
        ha.next(hb);
        hb.next(hc);

        ha.doHandler("ABC");
    }
}
// 输出
包含A,处理完成
包含B,处理完成
包含C,处理完成

如果业务相对复杂的话,那么客户端的工作会非常繁琐,代码臃肿。

若后续需求改动,客户端需要改动,不符合开闭原则。

产生这些问题的原因就是因为链式结构的组装过于复杂,对于复杂结构对象的创建,就会想到我们之前的建造者模式,来解决这个问题。

客户端只需指定处理的节点对象,无需关系其他事情,并且客户端指定的处理节点顺序不同,那么构造出来的链式结构也随之不同。

// 定义责任链
abstract class ChainAbs{

    ChainAbs chainAbs;

    void next(ChainAbs chainAbs){
        this.chainAbs = chainAbs;
    }

    abstract void doHandler();
}

class ChainA extends ChainAbs{

    @Override
    void doHandler() {
        System.out.println("a");
        chainAbs.doHandler();
    }
}

class ChainB extends ChainAbs{
    @Override
    void doHandler() {
        System.out.println("b");
        chainAbs.doHandler();
    }
}

class ChainC extends ChainAbs{
    @Override
    void doHandler() {
        System.out.println("c");
    }
}

// 定义构建者
class ChainBuilder {
    private ChainAbs chainAbsH;
    private ChainAbs chainAbsT;

    public ChainBuilder next(ChainAbs chainAbs){
        if(this.chainAbsH == null){
            this.chainAbsH = this.chainAbsT = chainAbs;
            return this;
        }else{
            this.chainAbsT.next(chainAbs);
            this.chainAbsT = chainAbs;
        }
        return this;
    }

    public void doHandler(){
        chainAbsH.doHandler();
    }
}

// 客户端调用
public static void main(String[] args) {
    ChainAbs ca = new ChainA();
    ChainAbs cb = new ChainB();
    ChainAbs cc = new ChainC();

    ChainBuilder chainBuilder = new ChainBuilder();
    chainBuilder.next(ca)
            .next(cb)
            .next(cc)
            .doHandler();
}

// 输出结果
a
b
c

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值