zoukankan      html  css  js  c++  java
  • 设计模式学习总结(二十一)--责任链模式

    定义

    职责链模式就是避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

    在职责链模式中我们可以随时随地的增加或者更改一个处理者,甚至可以更改处理者的顺序,增加了系统的灵活性。处理灵活性是增加了,但是有时候可能会导致一个请求无论如何也得不到处理,它会被放置在链末端,这个既是职责链的优点也是缺点。

    角色

    角色:

    • Handler: 抽象处理者。定义了一个处理请求的方法。所有的处理者都必须实现该抽象类。
    • ConcreteHandler: 具体处理者。处理它所负责的请求,同时也可以访问它的后继者。如果它能够处理该请求则处理,否则将请求传递到它的后继者。
    • Client: 客户类。

    优缺点

    优点:

    • 降低耦合度。它将请求的发送者和接受者解耦。

    • 简化了对象。使得对象不需要知道链的结构。

    • 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。

    • 增加新的请求处理类很方便。

    缺点

    • 不能保证请求一定被接收。

    • 系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。

    • 可能不容易观察运行时的特征,有碍于除错。

    实例

    学生请假

    请假单对象:

    /**
     * 请假单
     */
    public class LeaveForm {
    
        /** 请假天数 **/
        private  int number;
    
        /** 请假人 **/
        private String person;
    
        public LeaveForm(String person,int number){
            this.person = person;
            this.number = number;
        }
    
        public int getNumber() {
            return number;
        }
    
        public void setNumber(int number) {
            this.number = number;
        }
    
        public String getPerson() {
            return person;
        }
    
        public void setPerson(String person) {
            this.person = person;
        }
    }
    

    抽象处理者:

    /**
     * 抽象处理者
     */
    public abstract class Leader {
    
        /** 姓名 **/
        public String name;
    
        /** 后续处理者 **/
        protected Leader successor;
    
        public Leader(String name){
            this.name = name;
        }
    
        public void setSuccessor(Leader successor) {
            this.successor = successor;
        }
    
        public abstract void handleRequest(LeaveForm LeaveNode);
    
    }
    

    具体处理者:

    /**
     * 辅导员
     */
    public class Instructor extends Leader {
        public Instructor(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveForm LeaveNode) {
            //小于3天辅导员审批,否则传递给系主任
            if (LeaveNode.getNumber() <= 3) {
                System.out.println("辅导员" + name + "审批" + LeaveNode.getPerson()
                        + "同学的请假条,请假天数为"
                        + LeaveNode.getNumber() + "天。");
            } else {
                if (this.successor != null) {
                    this.successor.handleRequest(LeaveNode);
                }
            }
        }
    }
    
    /**
     * 系主任
     */
    public class DepartmentHead extends Leader {
        public DepartmentHead(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveForm LeaveNode) {
            //小于7天系主任审批,否则传递给院长
            if (LeaveNode.getNumber() <= 7) {
                System.out.println("系主任" + name + "审批" + LeaveNode.getPerson()
                        + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
            } else {
                if (this.successor != null) {
                    this.successor.handleRequest(LeaveNode);
                }
            }
        }
    }
    
    /**
     * 院长
     */
    public class Dean extends Leader {
    
        public Dean(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveForm LeaveNode) {
            //小于10天院长审批,否则传递给校长
            if (LeaveNode.getNumber() <= 10) {
                System.out.println("院长" + name + "审批"
                        + LeaveNode.getPerson() + "同学的请假条,请假天数为"
                        + LeaveNode.getNumber() + "天。");
            } else {
                if (this.successor != null) {
                    this.successor.handleRequest(LeaveNode);
                }
            }
        }
    }
    
    /**
     * 校长
     */
    public class President extends Leader {
        public President(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveForm LeaveNode) {
            //小于15天校长长审批,否则不允批准
            if (LeaveNode.getNumber() <= 15) {
                System.out.println("校长" + name + "审批"
                        + LeaveNode.getPerson() + "同学的请假条,请假天数为"
                        + LeaveNode.getNumber() + "天。");
            } else {
                System.out.println("请假天天超过15天,不批准...");
            }
        }
    }
    

    测试:

    public static void main(String[] args) {
        Leader instructor = new Instructor("冯强");       //辅导员
        Leader departmentHead = new DepartmentHead("冯晓强");    //系主任
        Leader dean = new Dean("张妲强");      //院长
        Leader president = new President("王望望");     //校长
    
        instructor.setSuccessor(departmentHead);       //辅导员的后续者是系主任
        departmentHead.setSuccessor(dean);             //系主任的后续者是院长
        dean.setSuccessor(president);                  //院长的后续者是校长
    
        //请假3天的请假条
        LeaveForm leaveNode1 = new LeaveForm("张三", 3);
        instructor.handleRequest(leaveNode1);
    
        //请假9天的请假条
        LeaveForm leaveNode2 = new LeaveForm("李四", 9);
        instructor.handleRequest(leaveNode2);
    
        //请假15天的请假条
        LeaveForm leaveNode3 = new LeaveForm("王五", 15);
        instructor.handleRequest(leaveNode3);
    
        //请假20天的请假条
        LeaveForm leaveNode4 = new LeaveForm("赵六", 20);
        instructor.handleRequest(leaveNode4);
    }
    

    控制台输出:

    辅导员冯强审批张三同学的请假条,请假天数为3天。
    院长张妲强审批李四同学的请假条,请假天数为9天。
    校长王望望审批王五同学的请假条,请假天数为15天。
    请假天天超过15天,不批准...
    
  • 相关阅读:
    面试题:Spring的理解
    静态块与静态变量
    构造方法与构造块的执行顺序(区别于static)
    子类调用父类的构造函数几种情况
    使用json遇到的问题
    页面加载,使用ajax查询某个类别,并且给它们添加(拼接)连接
    对某个商品的上下架状态进行改变
    SSH后台管理系统,实现查询+分页
    跟上Java8
    java中值传递和引用传递
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/11582709.html
Copyright © 2011-2022 走看看