当前位置: 首页 > news >正文

【设计模式】职责链模式

系列文章目录


文章目录

  • 系列文章目录
    • 加薪代码初步
    • 职责链模式
    • 职责链的好处
    • 加薪代码重构
  • 总结


在这里插入图片描述

在本篇文章,我们以申请加薪、请假这一事件为例,

加薪代码初步

无论是申请加薪还是请假,都是一种申请,申请就要有申请类别、申请内容、申请数量。

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 manageLevel,Request request){if(manageLevel == "经理"){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(manageLevel == "总监"){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(manageLevel == "总经理"){if(request.getRequestType() == "请假" && request.getNumber() <= 5) {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() + "元,再说吧");}}}}//客户端代码public static void main(String[] args) {//三个不同级别的管理者Manager manager = new Manager("老大");Manager director = new Manager("老二");Manager generalManager = new Manager("老三");//小张请求加薪10000元Request request = new Request();request.setRequestContent("加薪");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);}

这样的代码看着确实不够美观,在管理者类中结果的方法太长。有很多的分支判断,这是非常不好的设计。而且在增加其他的管理类别,比如项目经理、部门经理、人力总监等,那就意味着,都需要去更改这个类,这个类承担了太多的责任,这违背了我们的单一职责原则,增加新的管理类别,需要修改这个类,违背了开放-封闭原则。因为有多个管理类别,所以我们可以把这些管理这的类别分别做成管理者的子类,这就可以利用多态性来化解分支带来的僵化。针对经理无权,上报总监,总监无权再上报总经理这样的功能,我们可以把用户的请求传递。

这其实就是一种设计模式-- 职责链模式

职责链模式

职责链模式: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止

这里发出这个请求的客户端并不知道这当中的哪一个对象最终处理这个请求,这样系统的更改可以在不影响客户端的情况下动态的重新组织和分配责任。

职责链结构图:

在这里插入图片描述
Handler类,定义一个处理请示的接口

abstract class Handler{ protected  Handler successor;//设置继任者public void setSuccessor(Handler successor){this.successor = successor;}public abstract void handlerRequest(int request);}

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

//处理请求为0-10class ConcreteHandler1 extends Handler{@Overridepublic void handlerRequest(int request) {if(request>0 && request<10){System.out.println(this.getClass().getSimpleName() + "处理请求" + request);}else if(successor != null){successor.handlerRequest(request);}}}//处理请求为10-20class ConcreteHandler2 extends Handler{@Overridepublic void handlerRequest(int request) {if(request >=10 && request < 20){System.out.println(this.getClass().getSimpleName() + ",处理请求" + request);}else if(successor != null){successor.handlerRequest(request);}}}//处理请求为20-30class ConcreteHandler3 extends Handler{@Overridepublic void handlerRequest(int request) {if(request >=20 && request < 30){System.out.println(this.getClass().getSimpleName() + ",处理请求" + request);}else if(successor != null){successor.handlerRequest(request);}}}

客户端代码,向链上的具体处理者对象提交请求

   public static void main(String[] args) {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 X : requests){h1.handlerRequest(X);}}

职责链的好处

职责链模式中最关键的是当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。 这样做的好处就是不用管那个对象来处理,反正该请求会被处理。这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需要保持它所有的候选接受者的引用。这也就大大降低了耦合度了 。另外我们是在客户端来定义链的结构,也就是说,我可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。 但是需要注意一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理。 所以我们需要事前考虑全面。

加薪代码重构

Request请求类与原来一样。

	//管理者抽象类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);}@Overridepublic 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);}@Overridepublic 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);}@Overridepublic void requestApplications(Request request) {if(request.getRequestType() == "请假" && request.getNumber() <= 5) {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() + "元,再说吧");}}}

由于我们把原来的一个管理者类改成了一个抽象类和三个具体类,此时类之间的灵活性就大大增加了,如果我们需要扩展新的管理类别,只需要增加子类就可以。比如这个例子增加一个‘集团总裁’类,是完全没有问题的,只需要修改‘总经理类’即可,并不影响其他代码。下面是客户端如何编写:

 public static void main(String[] args) {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();request.setRequestType("加薪");request.setRequestContent("小张要加薪");request.setNumber(10000);manager.requestApplications(request4);}

总结

以上就是本文全部内容,本文主要向大家介绍了设计模式中的职责链,通过申请加薪这一实例,引出职责链模式基本代码,最后改造加薪代码为责任链模式。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持!

http://www.dtcms.com/a/391278.html

相关文章:

  • 22届考研(华为oD)-Java面经
  • 轻松实践:用Python实现“名字大作战”游戏,表白Zulu
  • EasyDSS视频直播点播平台如何为游戏直播提供超强技术底座?
  • MySQL----MVCC机制
  • 设计|str增量法|计算贡献
  • Spring中Controller层中容易搞混的注解
  • Git GitHub 个人账户创建教程
  • Python学习系统计划:从零到精通的科学路径
  • 解锁 JavaScript 的数学魔法:深入探索 Math 对象
  • dcm4che系列主要开源项目概述
  • 枚举深入解析
  • Qt中delete与deleteLater()的使用
  • AD5621(单通道缓冲电压输出DAC)芯片的详细用法
  • vLLM的面试题
  • 最优控制3 -- 动态规划-一个解析解的例子
  • 深入分析大众点评 Ajax 接口:直接请求 JSON 数据高效获取评论
  • 京东零售张科:DataAI Infra会成为驱动未来的技术基石
  • Java 运维中的一些常用命令
  • 用 go-commons 打造一套最小可行监控体系
  • 广东省省考备考(第一百零二天9.19)——言语(拔高突破第二节课)
  • 在vscode中,在powershell 下,如何进入子目录?
  • 易语言源码怎么制作软件 易语言源码和模块怎么做成软件
  • 4-2〔O҉S҉C҉P҉ ◈ 研记〕❘ WEB应用攻击▸目录遍历漏洞-B
  • 【Javaweb】http协议-请求与响应
  • 内网穿透系列十三:wstunnel 一款通过 Websocket 或 HTTP2 隧道传输的内网穿透工具
  • 【开关电源篇】自激振荡开关电源原理详解-从模块解析到故障维修
  • SpringBoot+Vue实现图片上传
  • C++ 函数指针与排序策略
  • 12分钟讲解Python核心理念
  • 01数据结构-串和KMP算法