• 【行为型模式】《大话设计模式》——读后感 (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部门的邮件
         李四你好,你申请的加薪金额过大,公司无法满足你的需求!

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

  • 相关阅读:
    考察数据结构(An Extensive Examination of Data Structures)
    考察数据结构——第一部分:数据结构简介[译]
    老生常谈
    使用DataSet的ReadXml和WriteXml方法
    要掌握Sql Server,我还差得远啊!
    新浪短信Web Service
    还是水晶报表
    两种报表组件的功能分析
    无限级分类(非递归算法/存储过程版/GUID主键)完整数据库示例_(4)显示记录
    c#方法中调用参数的值传递方式和引用传递方式,以及ref与out的区别
  • 原文地址:https://www.cnblogs.com/chen1-kerr/p/7197994.html
Copyright © 2020-2023  润新知