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

通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

该模式在生活中很常见,比如:汽车制造、物流分拣、食品加工、质量检测等等,生活中更多的是这样的非纯责任模式,也就是说,每个节点都会根据自己的职责操作自己对应的部分,然后转交下一节点处理;也有纯责任模式,比如质检,一旦某个节点出问题直接不合格并打回。这种模式一般是从低等级往高等级层层请求。

我们来举个团建经费申请的例子:

场景设定:

项目经理(500) - 部门主管(1000) - 总经理(2000) - 老板(2000~5000)

首先抽象出经理,并创建链的连接关系

package com.zndroid.dm.ChainOfResponseModel;

/**
 * Created by luzhenyu on 2017/9/18.
 */

/**抽象出可处理的对象,并提供‘链’的关联和具体类的处理请求*/
public abstract class Manager {
    public abstract void request(int mount);//请求入口

    public void setNextManager(Manager nextManager) {
        this.nextManager = nextManager;
    }

    protected Manager nextManager;//提供链关联

    public void done() {
        System.out.println("[OK...]");
    }
}

具体节点

package com.zndroid.dm.ChainOfResponseModel.impl;

import com.zndroid.dm.ChainOfResponseModel.Manager;

/**
 * Created by luzhenyu on 2017/9/18.
 */

public class ProjectManager extends Manager {
    @Override
    public void request(int mount) {
        if (mount <= 500) {
            System.out.println("项目经理审批通过,申请金额:" + mount);
            done();
            return;
        }
        else {
            System.out.println("金额超出项目经理的范围,开始转交上级处理...");
            nextManager.request(mount);
        }
    }
}
package com.zndroid.dm.ChainOfResponseModel.impl;

import com.zndroid.dm.ChainOfResponseModel.Manager;

/**
 * Created by luzhenyu on 2017/9/18.
 */

public class DepartmentManager extends Manager {
    @Override
    public void request(int mount) {
        if (mount > 500 && mount <= 1000) {
            System.out.println("部门主管审批通过,申请金额:" + mount);
            done();
            return;
        }
        else {
            System.out.println("金额超出部门主管的范围,开始转交上级处理...");
            nextManager.request(mount);
        }
    }
}
package com.zndroid.dm.ChainOfResponseModel.impl;

import com.zndroid.dm.ChainOfResponseModel.Manager;

/**
 * Created by luzhenyu on 2017/9/18.
 */

public class GeneralManager extends Manager {
    @Override
    public void request(int mount) {
        if (mount > 1000 && mount <= 2000) {
            System.out.println("总经理审批通过,申请金额:" + mount);
            done();
            return;
        }
        else {
            System.out.println("金额超出总经理的范围,开始转交上级处理...");
            nextManager.request(mount);
        }
    }
}
package com.zndroid.dm.ChainOfResponseModel.impl;

import com.zndroid.dm.ChainOfResponseModel.Manager;

/**
 * Created by luzhenyu on 2017/9/18.
 */

public class BossManager extends Manager {
    @Override
    public void request(int mount) {
        if (mount > 2000 && mount <= 5000) {
            System.out.println("老板审批通过,申请金额:" + mount);
            done();
            return;
        }
        else {
            System.out.println("老板哭穷中...");
        }
    }
}
使用如下
/**
         * 职责链模式
         * 使多个对象都有可能处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
         *
         * 往往它是一个从最低级到上层的请求方式,职责链模式可以灵活的改变内部的传递规则,每个人可以动态的制定自己的继承者。
         * 如果初始层级暂时不在或消失,请求也可以直接发送给其他层级,后续职责链还会继续进行。而且可以随时增加和修改处理一个请求的结构,增加了给对象指派的职责的灵活性。
         *
         * 优点:
         * 调用者不需知道具体谁来处理请求,也不知道链的具体结构,降低了节点域节点的耦合度;可在运行时动态修改链中的对象职责,增强了给对象指派职责的灵活性;
         * 缺点:
         * 没有明确的接收者,可能传到链的最后,也没得到正确的处理;系统性能会受到影响;代码调试比较繁琐。
         *
         * 具体应用:
         * OA系统;在java中的实际应用有Servlet中的过滤器(Filter);Struts2的拦截器(Interceptor),生活中大部分流程还是不纯的责任链,也就是每个节点的对象都有可能
         * 做了对应的操作,高层次的操作要以低层次的为依据,比如:公司请假肯定要部门经理先同意才能走到下一级,而不是说,部门经理不同意就会走到老板那。
         * */
        //下面来模拟一下公司的团建申请
        //比方说现在有三个老总可以处理团建申请,他们的可以批示的金额分变为:
        //项目经理(500) - 部门主管(1000) - 总经理(2000) - 老板(2000~5000)

        //创建节点:
        ProjectManager projectManager = new ProjectManager();
        DepartmentManager departmentManager = new DepartmentManager();
        com.zndroid.dm.ChainOfResponseModel.impl.GeneralManager  generalManager= new com.zndroid.dm.ChainOfResponseModel.impl.GeneralManager();
        BossManager bossManager = new BossManager();

        //建立链接:
        projectManager.setNextManager(departmentManager);
        departmentManager.setNextManager(generalManager);
        generalManager.setNextManager(bossManager);

        projectManager.request(3000);
        log("----------------我是分割线-----------------");
运行结果:

[ ======================================== ]
金额超出项目经理的范围,开始转交上级处理...
金额超出部门主管的范围,开始转交上级处理...
金额超出总经理的范围,开始转交上级处理...
老板审批通过,申请金额:3000
[OK...]
[ ----------------我是分割线----------------- ]
[ ======================================== ]



【欢迎上码】

【微信公众号搜索 h2o2s2】


猜你喜欢

转载自blog.csdn.net/luzhenyuxfcy/article/details/78020669