首页 > 其他分享 >设计模式(行为型设计模式——职责链模式)

设计模式(行为型设计模式——职责链模式)

时间:2024-03-19 13:33:46浏览次数:16  
标签:职责 处理 LeaveRequest 模式 String 设计模式 leaveRequest public 请求

设计模式(行为型设计模式——职责链模式)

职责链模式

基本定义

  • 为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

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

  • 在职责链模式中我们可以随时随地的增加或者更改一个处理者,甚至可以更改处理者的顺序,增加了系统的灵活性。

模式结构

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

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

  • Client:客户端

代码实现

Handler:抽象处理者
public abstract class Leader {

    private String position;//岗位

    Leader nextLeader;//下一节点审核人员

    public Leader(String position) {
        super();
        this.position = position;
    }

    public void setNextLeader(Leader nextLeader) {
        this.nextLeader = nextLeader;
    }

    //处理请求
    public abstract void process(LeaveRequest leaveRequest);
}
ConcreteHandler:具体处理者

组长 批准1天及以下假期, 职责链上的一个具体处理者

@Slf4j
public class GroupLeader extends Leader {

    public GroupLeader(String position) {
        super(position);
    }

    @Override
    public void process(LeaveRequest leaveRequest) {
        if(leaveRequest.getDays() <= 1){
            log.info("组长批准: 同意。【请假单:姓名{}, 请假天数: {} , 原因:{} 】",
                    leaveRequest.getName(),
                    leaveRequest.getDays() ,
                    leaveRequest.getReason());
        }else {
            if(nextLeader == null){
                log.info("该请假单不能被批准:{} ", leaveRequest);
            }
            nextLeader.process(leaveRequest);
        }
    }
}

经理-批准3天及以下, 职责链上的一个具体处理者

@Slf4j
public class ManageLeader extends Leader{

    public ManageLeader(String position) {
        super(position);
    }

    @Override
    public void process(LeaveRequest leaveRequest) {
        if(leaveRequest.getDays() <= 3){
            log.info("经理批准: 同意。【请假单:姓名{}, 请假天数: {} , 原因:{} 】",
                    leaveRequest.getName(),
                    leaveRequest.getDays() ,
                    leaveRequest.getReason());
        }else{
            if(nextLeader == null){
                log.info("该请假单不能被批准:{} ", leaveRequest);
                return;
            }
            nextLeader.process(leaveRequest);
        }
    }
}

CEO-批准5天及以下,职责链上的一个具体处理者

@Slf4j
public class CEOLeader extends Leader{

    public CEOLeader(String position) {
        super(position);
    }

    @Override
    public void process(LeaveRequest leaveRequest) {
        if(leaveRequest.getDays() <= 5){
            log.info("CEO批准: 同意。【请假单:姓名{}, 请假天数: {} , 原因:{} 】",
                    leaveRequest.getName(),
                    leaveRequest.getDays() ,
                    leaveRequest.getReason());
        }else{
            if(nextLeader == null){
                log.info("该请假单不能被批准:{} ", leaveRequest);
                return;
            }
            nextLeader.process(leaveRequest);
        }
    }
}
POJO: 普通Java类
@Getter
@Setter
public class LeaveRequest {

    private String name;
    private int days;
    private String reason;

    public LeaveRequest() {
    }

    public LeaveRequest(String name, int days, String reason) {
        this.name = name;
        this.days = days;
        this.reason = reason;
    }

    @Override
    public String toString() {
        return "LeaveRequest{" +
                "name='" + name + '\'' +
                ", days=" + days +
                ", reason='" + reason + '\'' +
                '}';
    }
}
Client:测试类
public class Test {
    public static void main(String[] args){
        Leader groupLeader = new GroupLeader("组长");
        Leader manageLeader = new ManageLeader("经理");
        groupLeader.setNextLeader(manageLeader);

        Leader ceo = new CEOLeader("总经理");
        manageLeader.setNextLeader(ceo);

        LeaveRequest oneDay = new LeaveRequest("林冲", 1, "爬山");

        LeaveRequest threeDays = new LeaveRequest("吴用", 3, "回家相亲");
        LeaveRequest fiveDays = new LeaveRequest("武松", 5, "去打猎");
        LeaveRequest sixDays = new LeaveRequest("李逵", 7, "去旅行");

        groupLeader.process(oneDay);
        groupLeader.process(threeDays);
        groupLeader.process(fiveDays);
        groupLeader.process(sixDays);
    }
}
输出结果

组长批准: 同意。【请假单:姓名林冲, 请假天数: 1 , 原因:爬山 】

经理批准: 同意。【请假单:姓名吴用, 请假天数: 3 , 原因:回家相亲 】

CEO批准: 同意。【请假单:姓名武松, 请假天数: 5 , 原因:去打猎 】

该请假单不能被批准:LeaveRequest{name=‘李逵’, days=7, reason=‘去旅行’}

优点

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

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

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

  • 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。

  • 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

缺点

  • 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。

  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。

  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

使用场景

  • 有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定。

  • 可动态指定一组对象处理请求,或添加新的处理者。

  • 在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

总结

  • 责链模式将请求的发送者和接受者解耦了。客户端不需要知道请求处理者的明确信息,甚至不需要知道链的结构,它只需要将请求进行发送即可。

  • 处理者不需要知道链的结构,只需要明白他的后续者是谁就可以了。这样就简化了系统中的对象。

  • 职责链模式能够非常方便的动态增加新职责或者删除职责。

  • 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。

标签:职责,处理,LeaveRequest,模式,String,设计模式,leaveRequest,public,请求
From: https://blog.csdn.net/weixin_44675056/article/details/136801826

相关文章

  • NodeJS 中的设计模式
    Node.js是一个流行的JavaScript运行时,允许开发者使用事件驱动、非阻塞I/O模型构建可扩展的网络应用程序。和任何复杂的框架一样,Node.js应用程序可以从使用成熟的设计模式中受益,以促进代码重用、可维护性和健壮性。本文将概述一些对Node.js开发非常有用的设计模式。......
  • 设计模式学习(一)单例模式的几种实现方式
    目录前言饿汉式懒汉式懒汉式DCLP局部静态式(Meyers'Singleton)单例模板参考文章前言单例模式,其核心目标是确保在程序运行的过程中,有且只有存在一个实例才能保证他们的逻辑正确性以及良好的效率。因此单例模式的实现思路就是确保一个类有且只有一个实例,并提供一个该实例的全局访问......
  • 策略模式实例
    目录需求描述代码实现初始化容器配置厂商类型枚举策略来源注解厂商来源工厂配置初始化来源工厂配置业务代码需求描述购买手机分为三个手机厂商:华为手机、小米手机、OPPO手机,根据每个手机厂商编码查看对应厂商旗舰手机。代码实现初始化容器配置importlombok.extern.slf4j.Slf......
  • 代理模式
    代理模式主要分为两种。静态代理动态代理学习Spring的AOP之前,需要了解代理模式。基于租房这一事件,抽象角色与行为。房东、房屋中介、租客房东和房屋中介的共同行为:出租房屋。静态代理举例一静态代理角色分析(括号内是本次举例中的角色)抽象角色:一般使用接口或者抽......
  • Web 开发模式演进过程
    作为初学者,要了解Web开发模式的演进过程,并从这些演进过程中看到变化,这样有利于开发者的思路提升。什么是Web开发Web:网页,可以通过浏览器访问的资源Web开发:基于网页载体的软件开发,以网页提供给用户进行业务功能操作Web应用:由多个静态和动态web资源组成,如:HTML、CS、......
  • gRPC的四种通信模式
    目录gRPC的四种通信模式一、RPC(UnaryRPC)二、服务端流RPC三、客户端流RPC四、双向流RPC五、综合案例5.1新建streamdemo.proto5.2执行命令,生成go文件5.3客户端5.4服务端六、总结gRPC的四种通信模式gRPC有四种通信⽅式,分别是:简单RPC(UnaryRPC)、服务端流式RPC(Serverstrea......
  • 【IT老齐045】RabbitMQ六种队列模式
    【IT老齐045】RabbitMQ六种队列模式前情提要Producer:生产者,消息的提供者Consumer:消费者,消息的使用者Broker:MQ服务器,管理队列、消息及相关信息Message:消息,程序间的通信的数据Queue:队列,消息存放的容器,消息先进先出Exchange:交换机,用于分发消息工作模式简单模式工作队列......
  • HDFS 安全模式
    HDFS安全模式安全模式概述:安全模式是HDFS所处的一种特殊状态,在这种状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求,是一种保护机制,用于保证集群中的数据块的安全性。在NameNode主节点启动时,HDFS首先进入安全模式,集群会开始检查数据块的完整性。DataNode在启动的......
  • mysql安全模式下创建账号
    1.首先停止mysql数据库服务2.进入mysql数据库的bin目录下,打开cmd,以--skip-grant-tables模式登录数据库,执行如下指令3.安全模式启动MYSQL数据库服务后,在MYSQL数据库的bin目录下打开第二个cmd4.以root账号登录mysql数据库:mysql-uroot5.查看数据库,执行SHOWDATABASES;6.......
  • 来自通义千问的观察者模式的实现
    Spring相关的实现BusinessProcessEvent.javapackagecom.example.demo.event;importorg.springframework.context.ApplicationEvent;publicclassBusinessProcessEventextendsApplicationEvent{privateStringinstanceId;privateStringoperationType;......