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

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 屏幕硬件参数选取

    屏幕硬件参数选取

    2021年7月20日
    60
  • saga分布式事务_本地事务和分布式事务

    saga分布式事务_本地事务和分布式事务在分布式系统中一次操作需要由多个服务协同完成,这种由不同的服务之间通过网络协同完成的事务称为分布式事务。本文详解介绍七种常见分布式事务的原理以及优缺点和适用场景(2PC、3PC、TCC、Saga、本地事务表、MQ事务消息、最大努力通知)

    2022年9月13日
    0
  • 104规约笔记「建议收藏」

    104规约笔记「建议收藏」电力系统中常见的设备分为调度端(控制站、主站、客户机),服务端(被控站、子站,典型设备包含TTU、RTU等),两者之间通过104规约来进行数据通信与传输。其传输层实际上使用的是TCP协议进行数据的传输。固定端口号为2404。《电力系统104规约帧报文解析》注意这里的调度端和服务端,调度端往往安装在PC电脑上,用网线连接(可靠的网络),服务端是工业设备:TTU(distributionTransformersupervisoryTerminalUnit,配电变压器监测终端)。RTU(远程终

    2022年6月20日
    32
  • [转载]Matlab fmincon函数用法

    [转载]Matlab fmincon函数用法原文地址:fmincon函数用法”style=”text-decoration:none;color:rgb(151,38,38)”>Matlab fmincon函数用法作者:长笛人倚楼Gloria这个函数在之前优化工具箱一文中已经介绍过,由于其应用广泛,所以这里通过实例单独整理一下其用法。一、基本介绍求解问题的标准型为minF(X)s.tAXAeqX=

    2022年5月16日
    29
  • nginx php apache php 对比,Apache和nginx的比较「建议收藏」

    nginx php apache php 对比,Apache和nginx的比较「建议收藏」nginx相对apache的优点:● 轻量级,同样起web服务,比apache占用更少的内存及资源● 抗并发,nginx处理请求是异步非阻塞的,而apache则是阻塞型的,在高并发下nginx能保持低资源低消耗高性能● 高度模块化的设计,编写模块相对简单● 社区活跃,各种高性能模块出品迅速啊● Nginx支持更多的并发连接,能够支持高达50000个并发连接数的相应● 能在不间断服务…

    2022年6月6日
    28
  • exit是什么意思(TerminateProcess)

    首先来谈谈一个进程的执行流程。每个应用程序都有个主函数,在WINDOWS下,只支持两种类型的应用程序——CUI(控制台应用程序)和GUI(图形界面应用程序),相应的,其主函数类型不同。来看下这几个入口函数int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE,PSTR pszCmdLine, int nCmdShow);    int WINAPT w

    2022年4月15日
    72

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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