Java设计模式(十七)之行为型模式:责任链模式

Java设计模式(十七)之行为型模式:责任链模式

学校规定所以去参加校招的必须要请假,且必须要有相关人员的签字,三天一下,辅导员签字、三到七天系主任签字,一个星期以上院长签字,更多?校长,出了这样的政策确实上课情况好多了!对于这中将请求一级一级地往上传递直到处理请求为止的设计模式就是职责链模式。

Java设计模式(十七)之行为型模式:责任链模式

上图将学生、辅导员、系主任、院长、校长组成了一个简单的链。在这个链上,学生是申请者,其余的都是请求处理者。职责链可以将请求的处理者组织成一条链,并且将请求沿着链传递,如果某个请求处理者能够处理请求则处理,否则将该请求交由上级处理。

职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了,这就是职责链的设计动机。

 

一、定义:

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

在职责链模式中最关键的一点就是客户提交请求后,请求沿着链往下传递直到有一个处理者处理它,在这里客户无需关心它的请求是哪个处理者来处理,反正总有一个处理者会处理它的请求。

在这里客户端和处理者都没有对方明确的信息,同时处理者也不知道职责链中的结构。所以职责链可以简化对象的相互连接,他们只需要保存一个指向其后续者的引用,而不需要保存所有候选者的引用。

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

 

二、模式结构:

UML结构图:

Java设计模式(十七)之行为型模式:责任链模式

从上面可以看出职责链包含三个角色:

(1)Handler: 抽象处理者。定义了一个处理请求的方法。所有的处理者都必须实现该抽象类。 

(2)ConcreteHandler: 具体处理者。处理它所负责的请求,同时也可以访问它的后继者。如果它能够处理该请求则处理,否则将请求传递到它的后继者。 

(3)Client: 客户类。

下面是最典型的具体处理者类:

public class ConcreteHandler extends Handler
{
    public void handleRequest(String request)
    {
        if(请求request满足条件)
        {
            ......  //处理请求;
        }
        else
        {
            this.successor.handleRequest(request); //转发请求
        }
    }
}

 

三、模式的实现:

我们将使用开头那个请假的实例。请假:3天以下辅导员签字、3到5天系主任签字、6到10天院长签字、11-15天校长签字、15天以上不允签字。

Java设计模式(十七)之行为型模式:责任链模式

首先是请假条:LeaveNode.java

public class LeaveNode {
    /** 请假天数 **/
    private  int number;
    
    /** 请假人 **/
    private String person;
    
    public LeaveNode(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;
    }
}

抽象处理者:Leader.java

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(LeaveNode LeaveNode);
}

四个具体处理者:辅导员:Instructor.java

public class Instructor extends Leader{
 
    public Instructor(String name){
        super(name);
    }
    
    public void handleRequest(LeaveNode LeaveNode) {
        if(LeaveNode.getNumber() <= 3){   //小于3天辅导员审批
            System.out.println("辅导员" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
        }
        else{     //否则传递给系主任
            if(this.successor != null){
                this.successor.handleRequest(LeaveNode);
            }
        }
    }
 
}

系主任: DepartmentHead.java

public class DepartmentHead extends Leader{
 
    public DepartmentHead(String name) {
        super(name);
    }
 
    public void handleRequest(LeaveNode LeaveNode) {
        if(LeaveNode.getNumber() <= 7){   //小于7天系主任审批
            System.out.println("系主任" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
        }
        else{     //否则传递给院长
            if(this.successor != null){
                this.successor.handleRequest(LeaveNode);
            }
        }
    }
}

 院长:Dean.java

public class Dean extends Leader{
 
    public Dean(String name) {
        super(name);
    }
 
    public void handleRequest(LeaveNode LeaveNode) {
        if(LeaveNode.getNumber() <= 10){   //小于10天院长审批
            System.out.println("院长" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
        }
        else{     //否则传递给校长
            if(this.successor != null){
                this.successor.handleRequest(LeaveNode);
            }
        }
    }
 
}

校长:President.java

public class President extends Leader{
 
    public President(String name) {
        super(name);
    }
 
    public void handleRequest(LeaveNode LeaveNode) {
        if(LeaveNode.getNumber() <= 15){   //小于15天校长长审批
            System.out.println("校长" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
        }
        else{     //否则不允批准
            System.out.println("请假天天超过15天,不批准...");
        }
    }
 
}

 客户端:Client.java

public class Client {
    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天的请假条
        LeaveNode leaveNode1 = new LeaveNode("张三", 3);
        instructor.handleRequest(leaveNode1);     
        
        //请假9天的请假条
        LeaveNode leaveNode2 = new LeaveNode("李四", 9);
        instructor.handleRequest(leaveNode2);
        
        //请假15天的请假条
        LeaveNode leaveNode3 = new LeaveNode("王五", 15);
        instructor.handleRequest(leaveNode3);
        
        //请假20天的请假条
        LeaveNode leaveNode4 = new LeaveNode("赵六", 20);
        instructor.handleRequest(leaveNode4);
    }
}

运行结果:

Java设计模式(十七)之行为型模式:责任链模式

 

四、责任链模式小结:

1、优点:

(1)降低耦合度。它将请求的发送者和接收者解耦。

(2)简化了对象。使得对象不需要链的结构。

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

(4)增加新的请求处理类很方便。

2、缺点:

(1)不能保证请求一定被接收。

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

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

3、适用场景:

(1)有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

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

(3)可动态指定一组对象处理请求。

4、职责链灵活在哪:

(1)改变内部的传递规则:

在内部,项目经理完全可以跳过人事部到那一关直接找到总经理。每个人都可以去动态地指定他的继任者。

(2)可以从职责链任何一关开始。

如果项目经理不在,可以直接去找部门经理,责任链还会继续,没有影响。

(3)用与不用的区别:

不用职责链的结构,我们需要和公司中的每一个层级都发生耦合关系。如果反映在代码上即使我们需要在一个类中去写上很多丑陋的if….else语句。如果用了职责链,相当于我们面对的是一个黑箱,我们只需要认识其中的一个部门,然后让黑箱内部去负责传递就好了。

5、纯的与不纯的责任链模式

(1)一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又把责任向下传的情况。

(2)在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。

(3)纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。

 

原博客链接:

https://blog.csdn.net/chenssy/article/details/11881377

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100067.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • html一个汉字空格占位_html空格字符

    html一个汉字空格占位_html空格字符1.&nbsp;(常用)不换行空格,全称No-BreakSpace,它是按下space键产生的空格。空格不会累加(只显示一个)。使用html表示才会累加,该空格占据宽度受字体影响。2.&ensp;半角空格,全称EnSpace,en为em宽度的一半(em类似于px受设置不同为20px=1em或其他自定义大小)。占据0.5个中文宽度,不受字体影响。3、&em…

  • centos6.5防火墙关闭命令(cmd关闭防火墙)

    cmd命令关闭防火墙netstopmpssvc CentOS6关闭防火墙使用以下命令,//临时关闭serviceiptablesstop//禁止开机启动chkconfigiptablesoffCentOS7中若使用同样的命令会报错,stop iptables.serviceFailedtostopiptables.service:Unitipt…

  • 【教程】Tomcat 的catalina.out 日志按照自定义日期格式进行切割

    本文简单介绍在使用cronolog对tomcat的日志进行自定义日期格式的切割,方便日志的整理和遇到问题日志的排查!安装cronolog安装cronolog的方法网上有很多,这里也简单的介绍一下。1.下载安装包 cronolog-1.6.2.tar.gz2.安装cronolog tar -zxvf cronolog-1.6.2.tar.gz …

  • Python的lambda表达式

    Python的lambda表达式1、lambda只是一个表达式,函数体比def简单很多2、lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去3、lambda函数拥有自己的名字空间,且不能访问自有参数列表之外或全局名字空间里的参数4、简单单行代码或者一次性的函数可以用lambda函数来书写,可以让代码更简洁。5、对于复杂函数或者函数体体量大的函数,最好不要用lambda函数,会增加代码的阅读难度,使代码晦涩难懂。6、在非多次调用的函数的情况下,lambda表达式即用既得,提高性能

    2022年10月18日
  • 设置pycharm背景颜色_python设置背景颜色

    设置pycharm背景颜色_python设置背景颜色PyCharm颜色设置选择主题和背景图片选择字体、修改字体大小新建颜色主题修改背景颜色修改注释颜色File  –>  Setting  (Ctrl+Shift+S)1、选择不同的主题、选择背景图片            Appearnce&Behavior  –>  Appearance2、字体                        Editor  –>  Font3、建…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号