【行为型模式】《大话设计模式》——读后感 (16)加薪非要老板批?——职责链模式

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

适用场景:

1、有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定;

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;

3、处理一个请求的对象集合应被动态指定。

Handler:

package com.sjmx.responsibility.application;

public abstract class Handler {
    /**
     * 持有下一个处理请求的对象
     */
    protected Handler successor = null;

    /**
     * 取值方法
     */
    public Handler getSuccessor() {
        return successor;
    }

    /**
     * 设置下一个处理请求的对象
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    /**
     * 处理聚餐费用的申请
     * 
     * @param user
     *            申请人
     * @param fee
     *            申请的钱数
     * @return 成功或失败的具体通知
     */
    public abstract String handleFeeRequest(String user, double fee);
}

ProjectManager:

package com.sjmx.responsibility.application;

public class ProjectManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {

        String str = "";
        // 项目经理权限比较小,只能在500以内
        if (fee < 500) {
            // 为了测试,简单点,只同意张三的请求
            if ("张三".equals(user)) {
                str = "成功:项目经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            } else {
                // 其他人一律不同意
                str = "失败:项目经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            }
        } else {
            // 超过500,继续传递给级别更高的人处理
            if (getSuccessor() != null) {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

DeptManager:

package com.sjmx.responsibility.application;

public class DeptManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {

        String str = "";
        // 部门经理的权限只能在1000以内
        if (fee < 1000) {
            // 为了测试,简单点,只同意张三的请求
            if ("张三".equals(user)) {
                str = "成功:部门经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            } else {
                // 其他人一律不同意
                str = "失败:部门经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            }
        } else {
            // 超过1000,继续传递给级别更高的人处理
            if (getSuccessor() != null) {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

GeneralManager:

package com.sjmx.responsibility.application;

public class GeneralManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {

        String str = "";
        // 总经理的权限很大,只要请求到了这里,他都可以处理
        if (fee >= 1000) {
            // 为了测试,简单点,只同意张三的请求
            if ("张三".equals(user)) {
                str = "成功:总经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            } else {
                // 其他人一律不同意
                str = "失败:总经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            }
        } else {
            // 如果还有后继的处理对象,继续传递
            if (getSuccessor() != null) {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

客户端:

package com.sjmx.responsibility.application;

public class Client {
     public static void main(String[] args) {  
            //先要组装责任链  
            Handler h1 = new GeneralManager();  
            Handler h2 = new DeptManager();  
            Handler h3 = new ProjectManager();  
            h3.setSuccessor(h2);  
            h2.setSuccessor(h1);  
              
            //开始测试  
            String test1 = h3.handleFeeRequest("张三", 300);  
            System.out.println("test1 = " + test1);  
            
            String test2 = h3.handleFeeRequest("李四", 300);  
            System.out.println("test2 = " + test2);  
            System.out.println("---------------------------------------");  
              
            String test3 = h3.handleFeeRequest("张三", 700);  
            System.out.println("test3 = " + test3);  
            String test4 = h3.handleFeeRequest("李四", 700);  
            System.out.println("test4 = " + test4);  
            System.out.println("---------------------------------------");  
              
            String test5 = h3.handleFeeRequest("张三", 1500);  
            System.out.println("test5 = " + test5);  
            String test6 = h3.handleFeeRequest("李四", 1500);  
            System.out.println("test6 = " + test6);  
        }  
      
}
test1 = 成功:项目经理同意【张三】的聚餐费用,金额为300.0元
test2 = 失败:项目经理不同意【李四】的聚餐费用,金额为300.0元
---------------------------------------
test3 = 成功:部门经理同意【张三】的聚餐费用,金额为700.0元
test4 = 失败:部门经理不同意【李四】的聚餐费用,金额为700.0元
---------------------------------------
test5 = 成功:总经理同意【张三】的聚餐费用,金额为1500.0元
test6 = 失败:总经理不同意【李四】的聚餐费用,金额为1500.0元

案例二:职责连模式与桥接模式整合

接口1系列

package com.net.sjms.responsiblity;
/**
 * @author 
 * @Time:2017年8月14日 下午5:26:08
 * @version 1.0
 * @description
 */
public abstract class Employ {
    
    private String name;
    
    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public abstract void apply(Handler handler, double money);
    
    public abstract void getMsg(String title, String msg);
    
}
package com.net.sjms.responsiblity;
/**
 * @author 
 * @Time:2017年8月14日 下午5:39:18
 * @version 1.0
 * @description
 */
public class Empoy1 extends Employ {
    
    @Override
    public void apply(Handler handler, double money)
    {
        handler.salery(this, money);
    }

    @Override
    public void getMsg(String title, String msg)
    {
        System.out.println(title);
        System.out.println("     " + msg);
    }

}

接口2系列

package com.net.sjms.responsiblity;

/**
 * @author 
 * @Time:2017年8月14日 下午5:18:13
 * @version 1.0
 * @description
 */
public abstract class Handler {
    
    public Handler nextNode;

    public Handler getNextNode()
    {
        return nextNode;
    }

    public void setNextNode(Handler nextNode)
    {
        this.nextNode = nextNode;
    }
    
    public abstract  void salery(Employ employ, double money);
}
package com.net.sjms.responsiblity;
/**
 * @author 
 * @Time:2017年8月14日 下午5:21:50
 * @version 1.0
 * @description
 */
public class FirstDev extends Handler {

    @Override
    public void salery(Employ employ, double money)
    {
        if(money < 1000)
        {
            employ.getMsg("来自FirstDev部门的邮件", employ.getName() + "你好,本部门同意你的加申请");
        }else
        {
            getNextNode().salery(employ, money);
        }
    }    
 
}
package com.net.sjms.responsiblity;
/**
 * @author 
 * @Time:2017年8月14日 下午5:22:07
 * @version 1.0
 * @description
 */
public class SecDev extends Handler {

    @Override
    public void salery(Employ employ, double money)
    {
        if(money < 2000)
        {
            employ.getMsg("来自SecDev部门的邮件", employ.getName() + "你好,本部门同意你的加申请");
        }else
        {
            getNextNode().salery(employ, money);
        }
        
    }
}
package com.net.sjms.responsiblity;

/**
 * @author 
 * @Time:2017年8月14日 下午5:37:59
 * @version 1.0
 * @description
 */
public class ThridDev extends Handler {

    @Override
    public void salery(Employ employ, double money)
    {
        if (money < 3000) {
            employ.getMsg("来自ThridDev部门的邮件", employ.getName() + "你好,本部门同意你的加申请");
        } else {
            employ.getMsg("来自ThridDev部门的邮件", employ.getName() + "你好,你申请的加薪金额过大,公司无法满足你的需求!");
        }
    }

}
package com.net.sjms.responsiblity;
/**
 * @author  
 * @Time:2017年8月14日 下午5:43:38
 * @version 1.0
 * @description
 */
public class Client {
    
    public static void main(String[] args)
    {
        Handler handler1 = new FirstDev();
        Handler handler2 = new SecDev();
        Handler handler3 = new ThridDev();
        
        handler1.setNextNode(handler2);
        handler2.setNextNode(handler3);
        
        Empoy1 e1 = new Empoy1();
        e1.setName("张三");
        e1.apply(handler1, 1500);
        
        Empoy1 e2 = new Empoy1();
        e2.setName("李四");
        e2.apply(handler1, 3500);
        
    }
    
}

运行结果:

来自SecDev部门的邮件
     张三你好,本部门同意你的加申请
来自ThridDev部门的邮件
     李四你好,你申请的加薪金额过大,公司无法满足你的需求!

说明:桥接模式一般是一个抽象类持有另一个接口,而我在此处稍微的做了变化,是将一个接口的具体实现类当做参数传递,希望你还认识桥接模式哦 @

原文地址:https://www.cnblogs.com/chen1-kerr/p/7197994.html