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)


相关推荐

  • rocketmq负载均衡机制_rocketmq topic

    rocketmq负载均衡机制_rocketmq topicProducer发送消息时,会首先获取Topic路由信息(通过本地+注册中心拉取),RocketMQ的架构里有多个Broker服务器,而消息队列也会存在于多个Broker服务器里,所以就需要负载均衡策略来将流量尽可能均匀的打到所有服务器上。本章节就介绍一下RocketMQ中常用的四种负载均衡策略。找到Producer发送消息时选择消息队列的逻辑,在类中定义了方法:进入到方法里:上述代码的类中定义了方法:根据源码可以很清楚地看到,默认策略就是依次选择消息队列进行发送,具体的执行细节如下:如何选一个

    2022年10月13日
  • windows远程桌面和teamviewer_windows远程桌面端口

    windows远程桌面和teamviewer_windows远程桌面端口Windows的远程桌面输错了一次密码,然后就怎么都连接不上了,查了半天发现傻缺360会默认屏蔽Windows的远程桌面和数据库连接…..大家没事都卸载了360吧转载于:https://www.cnblogs.com/JiangOil/p/10561828.html…

  • vs2013安装失败解决办法_个人总结及解决方案

    vs2013安装失败解决办法_个人总结及解决方案今晚上,在机器上安装vs2008时,连续好几次都失败,开始以为是vs2005(之前装的2005)的原因,后来把2005全卸载了,还是安装失败,在错误日志里总是说版本冲突,经过网上前人经验的指点问题得到了解决,现将前辈的经验收藏分享,以造福更多的人我就开始看我indows系统的日志,没有任何红色提示,但我始终不相信我的安装文档有问题,因为同事他们也是用的这个版本(vs2008team),我更…

  • 工作中总结前端开发流程–vue项目

    工作中总结前端开发流程–vue项目

  • 计算机网络————IP地址分类以及网络地址的计算[通俗易懂]

    计算机网络————IP地址分类以及网络地址的计算[通俗易懂]一,IP地址分类 1.二进制与十进制的关系 2,IP地址的地址结构及分类IP地址结构:网络号+主机号网络号:中主机中指明中的所在物理网络的编号主机号:中中中主机在物理网络中的编号 IP地址分类:A类(大型),B类(中型),C类(小型),D类(组播),E类(保留地址-研究时使用) A类地址默认掩码:255.0.0.0/8B类地址默认掩码:2…

  • strncpy和strcpy区别_C语言strncpy

    strncpy和strcpy区别_C语言strncpyDefinedinheader <string.h>char *strncpy( char *dest, const ch

发表回复

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

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