软件设计模式第二篇(责任链模式)

什么是责任链模式

责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。

业务场景

如果一个公司的员工,他只需要在OA系统中提交请假单,然后根据假期的长短会流转到项目经理,部门经理,总经理等,而员工不需要知道谁批假期,他只关心假期是否已经获得领导同意和批准,这就达到了业务解耦的作用

根据以上业务,我们看下类图

软件设计模式第二篇(责任链模式)_第1张图片
从上图可以看到里面一共涉及到了三个角色:

(1)Handler:抽象处理者。它规范了每一个具体处理者的信息。

(2)ConcreteHandler:具体处理者。可以自己处理,也可以交给自己的下家处理。

(3)Client:客户端。向处理者提交请求对象

下面看看具体代码的实现

代码实现责任链模式

  1. 编写一个抽象类Handler
/**
 * @Author: dengcs
 * @Date: 2020/6/23 16:24
 * Comment:
 */
public abstract class Handler {
	//指定消息继承人
    protected Handler successor;
    public abstract void handler(String  msg);
    public abstract void setSuccessor(Handler successor);
    public abstract Handler getSuccessor();
    
}
  1. 具体实现类(项目经理ProjManager)
/**
 * @Author: dengcs
 * @Date: 2020/6/23 16:29
 * Comment:
 */
public class ProjManager extends Handler {
	//指定消息继承人
    //private Handler successor;
    @Override
    public void handler(String msg) {
        System.out.println("项目经理处理不了,交给上一级");
        this.successor.handler(msg);
    }

    @Override
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    @Override
    public Handler getSuccessor() {
        return successor;
    }
}

  1. 具体实现类(部门经理DeptManager)
/**
 * @Author: dengcs
 * @Date: 2020/6/23 16:29
 * Comment:
 */
public class DeptManager extends Handler {
	//指定消息继承人
    //private Handler successor;
    @Override
    public void handler(String msg) {
        System.out.println("部门经理处理不了,交给上一级");
        this.successor.handler(msg);
    }

    @Override
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    @Override
    public Handler getSuccessor() {
        return successor;
    }
}

  1. 具体实现类(总经理GeneManager)

总经理具有最大的权限,可以处理任何事情,链式中最后一环

/**
 * @Author: dengcs
 * @Date: 2020/6/23 16:29
 * Comment:
 */
public class GeneManager extends Handler {
	//指定消息继承人
    //private Handler successor;
    @Override
    public void handler(String msg) {
        System.out.println("总经理直接处理");
        //this.successor.handler(msg); 不需要再传递
    }

    @Override
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    @Override
    public Handler getSuccessor() {
        return successor;
    }
}

可以发现,我们可以为每一个具体实现者设置下一任执行者,当然到达食物链最顶尖的那个可以不设置。

测试

代码基本完成,编写一个客户端代码进行测试

/**
 * @Author: dengcs
 * @Date: 2020/6/23 16:40
 * Comment:
 */
public class Client {

    public static void main(String[] args) {
        String msg = "你好,我请一天假";
        ProjManager projManager = new ProjManager();
        DeptManager deptManager = new DeptManager();
        GeneManager geneManager = new GeneManager();

        //为每一级指定执行者,最后一环geneManager可以不指定
        projManager.setSuccessor(deptManager);
        deptManager.setSuccessor(geneManager);

        //交给第一级执行
        projManager.handler(msg);
    }
}

执行main函数后,结果为

项目经理处理不了,交给上一级
部门经理处理不了,交给上一级
总经理直接处理

我们在这里指定了项目经理的下一任处理者是部门经理,部门经理的下一任处理者是总经理,没有为总经理指派下一任处理者,输出来的结果就是这样。不过还有一种情况,也就是五百里加急的情报,项目经理可以直接上报给总经理处理,不经过部门经理,这种方式也是可以的。

写在最后

最后我们总结一下责任链模式的优缺点

该模式的优点,我在上面也说了,就在于实现了解耦,符合开闭原则,在这里面调用者不需要知道具体的传递过程,他只需要知道最终的结果被处理了。而且这个链表的结构可以被灵活的更改重组。

但是它的缺点也是很明显的,首先从性能上说起,一个是调用时间,如果链表在最开始被处理了还好,万一链表跑到了最后一个才被处理,那么他的调用时间肯定会比不适用责任链模式的效率要低一些;
第二是内存的问题,我们会构造出很多的链表节点对象,但是有些对象在我们的应用场景中是不会用到的,所以大大的消耗了我们的内存;

总之,责任链模式不能乱用,我们不能因模式而模式,如果有更好的模式可以代替我们的责任链模式的话,可以考虑去替代它。

源码下载地址demo

如果要了解更多的设计模式,请关注我吧。

你可能感兴趣的:(软件设计模式第二篇(责任链模式))