加薪非要老总批?--责任链模式

news2024/12/24 2:32:11

1.1 老板,我要加薪

         "我和刚进来的几个同事比较,我觉得我做得很好。公司每每分配的任务,我基本都可以快速完成。有一次,一段程序需要增加一个分支条件,我立刻想到利用反射、工厂等设计模式来处理,经理对我的设计很满意。"   我要求转正加薪。 

1.2 加薪代码初步

        加薪代码实现,无论加薪还是请假,都是一种申请,申请就应该有申请类别,申请内容和申请数量。然后我觉得经理,总监,总经理都是管理者,应该对申请流程作出判断,是否有权决策。

package code.chapter24.chainofresponsibility1;

public class Test {

    public static void main(String[] args) {

        System.out.println("**********************************************");       
        System.out.println("《大话设计模式》代码样例");
        System.out.println(); 

        Manager manager = new Manager("金利");
        Manager director = new Manager("宗剑");
        Manager generalManager = new Manager("钟精励");

        Request request = new Request();
        request.setRequestType("加薪");
        request.setRequestContent("小菜请求加薪");
        request.setNumber(10000);

        manager.getResult("经理", request);
        director.getResult("总监", request);
        generalManager.getResult("总经理", request);

        Request request2 = new Request();
        request2.setRequestType("请假");
        request2.setRequestContent("小菜请假");
        request2.setNumber(3);

        manager.getResult("经理", request2);
        director.getResult("总监", request2);
        generalManager.getResult("总经理", request2);
        
        System.out.println();
        System.out.println("**********************************************");
    }
}

//申请
class Request {
    //申请类别
    private String requestType;
    public String getRequestType(){
        return this.requestType;
    }
    public void setRequestType(String value){
        this.requestType = value;
    }

    //申请内容
    private String requestContent;
    public String getRequestContent(){
        return this.requestContent;
    }
    public void setRequestContent(String value){
        this.requestContent = value;
    }

    //数量
    private int number;
    public int getNumber(){
        return this.number;
    }
    public void setNumber(int value){
        this.number = value;
    }
}

//管理者
class Manager{
    protected String name;
    public Manager(String name){
        this.name = name;
    }

    public void getResult(String managerLevel,Request request){
        if (managerLevel == "经理"){
          if (request.getRequestType()=="请假" && request.getNumber()<=2)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
          else 
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,我无权处理");
        }
        else if (managerLevel == "总监"){
          if (request.getRequestType()=="请假" && request.getNumber()<=5)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
          else 
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,我无权处理");
        }
        else if (managerLevel == "总经理"){
          if (request.getRequestType()=="请假")
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
          else if (request.getRequestType()=="加薪" && request.getNumber()<=5000)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,被批准");
          else if (request.getRequestType()=="加薪" && request.getNumber()>5000)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,再说吧");
        }
    }
}

        "那个'管理者'类吧,里面的'结果'方法比较长,加上有太多的分支判断,这其实是非常不好的设计。"
        "说得不错,因为你很难讲当中还会不会增加其他的管理类别,比如项目经理、部门经理、人力总监、副总经理等。那就意味着都需要去更改这个类,这个类承担了太多的责任,这违背了哪些设计原则?"
        "类有太多的责任,这违背了单一职责原则,增加新的管理类别,需要修改这个类,违背了开放-封闭原则。"
        "说得好,那你觉得应该如何下手去重构它呢?"
        "你刚才提到了可能会增加管理类别,那就意味着这里容易变化,我想把这些公司管理者的类别分别做成管理者的子类,这就可以利用多态性来化解分支带来的僵化。"
        "那如何解决经理无权上报总监,总监无权再上报总经理这样的功能呢?"
        "我想让它们之间有一定的关联,把用户的请求传递,直到可以解决这个请求为止。"
"说得不错,你其实已经说到了一个行为设计模式'职责链模式'的意图了。"

1.3 责任链模式

        职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。[DP]
        "这里发出这个请求的客户端并不知道这当中的哪一个对象最终处理这个请求,这样系统的更改可以在不影响客户端的情况下动态地重新组织和分配责任。"
        "听起来感觉不错哦,但如何做呢?"
"我们来看看结构图。"
职责链模式(Chain of Responsibility)结构图

package code.chapter24.chainofresponsibility0;

public class Test {

    public static void main(String[] args) {

        System.out.println("**********************************************");       
        System.out.println("《大话设计模式》代码样例");
        System.out.println(); 

        Handler h1 = new ConcreteHandler1();
        Handler h2 = new ConcreteHandler2();
        Handler h3 = new ConcreteHandler3();
        h1.setSuccessor(h2);
        h2.setSuccessor(h3);

        int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };

        for(int request : requests) {
            h1.handleRequest(request);
        }
 
        System.out.println();
        System.out.println("**********************************************");
    }
}

abstract class Handler{
    protected Handler successor;

    //设置继任者
    public void setSuccessor(Handler successor){
        this.successor = successor;
    }

    public abstract void handleRequest(int request);
}

class ConcreteHandler1 extends Handler{
    public void handleRequest(int request){
        if (request >=0 && request < 10){
            System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
        }
        else if (successor != null){
            successor.handleRequest(request);
        }
    }
}

class ConcreteHandler2 extends Handler{
    public void handleRequest(int request){
        if (request >=10 && request < 20){
            System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
        }
        else if (successor != null){
            successor.handleRequest(request);
        }
    }
}

class ConcreteHandler3 extends Handler{
    public void handleRequest(int request){
        if (request >=20 && request < 30){
            System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
        }
        else if (successor != null){
            successor.handleRequest(request);
        }
    }
}


Handler类,定义一个处理请示的接口。
ConcreteHandler类,具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则就将该请求转发给它的后继者。
ConcreteHandler1,当请求数为0~10则有权处理,否则转到下一位。
ConcreteHandler2,当请求数为10~20则有权处理,否则转到下一位。

ConcreteHandler3,当请求数为20~30则有权处理,否则转到下一位。
客户端代码,向链上的具体处理者对象提交请求。

1.4 责任链模式的好处

        "这当中最关键的是当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。[DP]"
        "这样做的好处是不是说请求者不用管哪个对象来处理,反正该请求会被处理就对了?"
        "是的,这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用[DP]。这也就大大降低了耦合度了。"
        "我感觉由于是在客户端来定义链的结构,也就是说,我可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性[DP]。"
        "是的,这的确是很灵活,不过也要当心,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,这就很糟糕了。需要事先考虑全面。"
        "哈,这就跟现实中邮寄一封信,因地址不对,最终无法送达一样。"
        "是的,就是这个意思。就刚才的例子而言,最重要的有两点,一个是你需要事先给每个具体管理者设置他的上司是哪个类,也就是设置后继者。另一点是你需要在每个具体管理者处理请求时,做出判断,是可以处理这个请求,还是必须要'推卸责任',转移给后继者去处理。"
        "哦,我明白你的意思了,其实就是把我现在写的这个管理者类当中的那些分支,分解到每一个具体的管理者类当中,然后利用事先设置的后继者来实现请求处理的权限问题。"

1.5 加薪代码重构

        "是的,所以我们先来改造这个管理者类,此时它将成为抽象的父类了,其实它就是Handler。"
代码结构图

package code.chapter24.chainofresponsibility2;

public class Test {

    public static void main(String[] args) {

        System.out.println("**********************************************");       
        System.out.println("《大话设计模式》代码样例");
        System.out.println(); 

        CommonManager manager = new CommonManager("金利");
        Director director = new Director("宗剑");
        GeneralManager generalManager = new GeneralManager("钟精励");
        manager.setSuperior(director);
        director.setSuperior(generalManager);

        Request request = new Request();
        request.setRequestType("请假");
        request.setRequestContent("小菜请假");
        request.setNumber(1);
        manager.requestApplications(request);

        Request request2 = new Request();
        request2.setRequestType("请假");
        request2.setRequestContent("小菜请假");
        request2.setNumber(4);
        manager.requestApplications(request2);

        Request request3 = new Request();
        request3.setRequestType("加薪");
        request3.setRequestContent("小菜请求加薪");
        request3.setNumber(5000);
        manager.requestApplications(request3);

        Request request4 = new Request();
        request4.setRequestType("加薪");
        request4.setRequestContent("小菜请求加薪");
        request4.setNumber(10000);
        manager.requestApplications(request4);
 
        System.out.println();
        System.out.println("**********************************************");
    }
}

//申请
class Request {
    //申请类别
    private String requestType;
    public String getRequestType(){
        return this.requestType;
    }
    public void setRequestType(String value){
        this.requestType = value;
    }

    //申请内容
    private String requestContent;
    public String getRequestContent(){
        return this.requestContent;
    }
    public void setRequestContent(String value){
        this.requestContent = value;
    }

    //数量
    private int number;
    public int getNumber(){
        return this.number;
    }
    public void setNumber(int value){
        this.number = value;
    }
}

//管理者抽象类
abstract class Manager{
    protected String name;
    public Manager(String name){
        this.name = name;
    }

    //设置管理者上级
    protected Manager superior;
    public void setSuperior(Manager superior){
        this.superior = superior;
    }

    //请求申请
    public abstract void requestApplications(Request request);
}

//普通经理
class CommonManager extends Manager{
    public CommonManager(String name){
        super(name);
    }

    public void requestApplications(Request request){
        if (request.getRequestType()=="请假" && request.getNumber()<=2)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
        else {
            if (this.superior != null)
                this.superior.requestApplications(request);
        }
    }
}

//总监
class Director extends Manager{
    public Director(String name){
        super(name);
    }

    public void requestApplications(Request request){
        if (request.getRequestType()=="请假" && request.getNumber()<=5)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
        else {
            if (this.superior != null)
                this.superior.requestApplications(request);
        }
    }
}

//总经理
class GeneralManager extends Manager{
    public GeneralManager(String name){
        super(name);
    }

    public void requestApplications(Request request){
        if (request.getRequestType()=="请假"){
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
        }
        else if (request.getRequestType()=="加薪" && request.getNumber()<=5000){
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,被批准");
        }
        else if (request.getRequestType()=="加薪" && request.getNumber()>5000){
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,再说吧");
        }
    }
}





        Request请求类与原来一样。
        "经理类就可以去继承这个'管理者'类,只需重写'申请请求'的方法就可以了。"
        "'总监'类同样继承'管理者类'。"
        "'总经理'的权限就是全部都需要处理。"
        "由于我们把你原来的一个'管理者'类改成了一个抽象类和三个具体类,此时类之间的灵活性就大大增加了,如果我们需要扩展新的管理者类别,只需要增加子类就可以。比如这个例子增加一个'集团总裁'类,完全是没有问题的,只需要修改'总经理类'即可,并不影响其他类代码。目前,还有一个关键,那就是客户端如何编写。"

        "嗯,这的确是很好地解决了原来大量的分支判断造成难维护、灵活性差的问题。"

1.6 加薪成功

        一段时间你的工作情况,你的积极表现和非常优秀的编程能力总经理也是非常肯定的。所以他最终答应了你的申请,给你加薪,从下个月开始实施。        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1574505.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

移除元素 -- 力扣第27题 -- 暴力、双指针解法

题目 https://leetcode.cn/problems/remove-element/description/ 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并原地修改输…

Maven--lib分离的打包方式

就是把lib包和source源码分开打包。优势就是&#xff0c;面对频繁更新的应用场景时&#xff0c;可以只更新源码包&#xff08;当然&#xff0c;前提是你的依赖没有增减&#xff09;。尤其是使用jenkins更新项目时&#xff0c;会省去很多时间吧&#xff1f; 不同项目的 lib之间不…

yolov9直接调用zed相机实现三维测距(python)

yolov9直接调用zed相机实现三维测距&#xff08;python&#xff09; 1. 相关配置2. 相关代码2.1 相机设置2.2 测距模块2.2 实验结果 相关链接 此项目直接调用zed相机实现三维测距&#xff0c;无需标定&#xff0c;相关内容如下&#xff1a; 1. yolov4直接调用zed相机实现三维测…

传统海外仓的管理模式有什么缺点?使用位像素海外仓系统的海外仓有什么优势?

传统的海外仓管理模式主要需要大量的人工操作和相对简单的信息化手段进行仓库的日常运营。因此&#xff0c;传统海外仓的运作比较依赖仓库员工的手工记录、核对和处理各种仓储和物流信息。 然而&#xff0c;传统海外仓管理模式通常存在一些缺点&#xff1a; 效率低下 因为需…

【数据结构】红黑树详解

目录 前言&#xff1a; 红黑树的概念&#xff1a; 红黑树的性质: 红黑树节点的定义&#xff1a; 红黑树的插入&#xff1a; 情况1&#xff1a;cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;u存在且为红 情况2&#xff1a;cur为红&#xff0c;p为红&#xff0c…

数据同步工具datax安装配置与示例

文章目录 一、部署步骤1、jdk环境2、python环境步骤一&#xff1a;安装方式一&#xff1a;官网下载安装包方式二&#xff1a;brew命令安装 步骤二&#xff1a;配置环境变量步骤三&#xff1a;验证 3、maven环境&#xff08;可选&#xff09; 二、下载安装datax1、下载datax源码…

CLCD 流水线发布SpringBoot项目

目录 一、流水线 1.1 点击进入流水线 1.2 新建流水线 二、添加流水线 三、构建上传和构建镜像 ​编辑 四、Docker部署 一、流水线 1.1 点击进入流水线 1.2 新建流水线 二、添加流水线 三、构建上传和构建镜像 在构建上传里添加一个步骤&#xff1a;构建镜像&#xff0c;这…

【环境变量】基本概念理解 | 查看环境变量echo | PATH的应用和修改

目录 前言 基本概念&理解 注意的点 查看环境变量的方法 PATH环境变量 PTAH应用系统指令 PTAH应用用户程序 命令行参数的修改&#xff08;内存级&#xff09; 配置文件的修改 windows环境变量 大家天天开心&#x1f642; bash进程的流程。环境变量在系统指…

实战经验,公众号选题方向大盘点!

公众号是重要的内容传播平台&#xff0c;每个品牌都有自己的公众号&#xff0c;公众号选题选得好不好&#xff0c;直接决定你这篇文章是否会爆&#xff0c;公众号的选题决定了文章的阅读量和粉丝增长数量。一个好的选题带来的利益是多方面的。 选题是每个品牌和企业绞尽脑汁去…

background背景图参数边渐变CSS中创建背景图像的渐变效果

效果:可以看到灰色边边很难受,希望和背景融为一体 原理: 可以使用线性渐变&#xff08;linear-gradient&#xff09;或径向渐变&#xff08;radial-gradient&#xff09;。以下是一个使用线性渐变作为背景图像 代码: background: linear-gradient(to top, rgba(255,255,255,0)…

【Unity每日一记】如何从0到1将特效图集制作成一个特效

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

Flink常见面试问题(附答案)

目录 基础篇1. 什么是Apache Flink&#xff1f;2. Flink与Hadoop的区别是什么&#xff1f;3. Flink中的事件时间&#xff08;Event Time&#xff09;和处理时间&#xff08;Processing Time&#xff09;有什么区别&#xff1f;4. Flink的容错机制是如何实现的&#xff1f;5. 什…

Myelsa的Python函数之旅(高铁直达)

一、函数的定义&#xff1a; 函数(Function)是一段可重复使用的代码块&#xff0c;用于执行特定的任务或计算&#xff0c;并可以接受输入参数和返回输出结果。函数可以将复杂的问题分解为更小的子问题&#xff0c;提高代码的可读性和可维护性。 二、函数的组成&#xff1a; 在…

设计模式总结-适配器模式

适配器模式 模式动机模式定义模式结构适配器模式实例与解析实例一&#xff1a;仿生机器人实例二&#xff1a;加密适配器 总结 模式动机 在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式。 通常情况下&#xff0c;客户端可以通过目标类的接口访问它所提供的…

Redis性能瓶颈与安全隐患排查验证纪实

在写《Redis怎样保证数据安全&#xff1f;》这篇文章&#xff0c;我是有对redis设置密码需要哪些步骤&#xff0c;设置密码的性能损耗有验证的。这就涉及到要对redis的配置做修改。 开始时我是打算采用直接使用redis配置文件的方式。所以我从redis官网下载了一个默认的配置文件…

java实现运行脚本文件

在最近的项目中&#xff0c;有一个需求是前端传给我一个脚本文件&#xff0c;然后我需要运行脚本文件后将结果进行返回&#xff0c;那接下来就让我们看看是怎么做的吧&#xff01; public R runScripts(Integer id) {ScriptsInfo scriptsInfo this.baseMapper.selectById(id);…

影响力营销与AI的结合:Kompas.ai在搭桥角色中的独特价值

在数字化营销的新时代&#xff0c;影响力营销已经成为品牌建立信任和提升市场影响力的有效手段。通过与关键意见领袖&#xff08;KOL&#xff09;的合作&#xff0c;品牌能够利用KOL的信誉和影响力来扩大其市场覆盖范围和提升品牌认知度。然而&#xff0c;寻找与品牌价值观相契…

汇编语言:寻址方式在结构化数据访问中的应用——计算人均收入

有一年多没有在CSDN上发博文了。人的工作重心总是有转移的&#xff0c;庆幸一直在做着有意义的事。   今天的内容&#xff0c;是为汇编语言课程更新一个实验项目。      本方案修改自王爽编《汇编语言》第&#xff14;版P172“实验7寻址方式在结构化数据访问中的应用” …

科普|老隋分享的人力资源项目怎么样?可不可以赚钱?

近年来&#xff0c;随着市场竞争的加剧和企业对人才需求的不断提升&#xff0c;人力资源项目逐渐成为了创业者和投资者关注的焦点。老隋作为一位在人力资源领域深耕多年的专业人士&#xff0c;经常分享关于人力资源项目的见解和经验。那么&#xff0c;老隋分享的人力资源项目究…