大话设计模式笔记(二十一)の职责链模式
职责链模式
定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
UML图
好处
- 当客户提交一个请求时,请求是沿链传递直至有一个 ConcreteHandler 对象负责处理它
- 接收者和发送者都没有对方的明确信息,且链中对象自己也并不知道链的结构。结果时职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需要保持他所有的候选者接收者的引用。
- 可以随时的增加或修改一个请求的结构,增强给对象指派职责的灵活性
但需要注意的是:一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理。
举个栗子
员工申请加薪,需要走流程
Talk is cheap, show me the code
(屁话少说,放码过来)
1. /**
2. * 管理者
3. * Created by callmeDevil on 2019/12/14.
4. */
5. public abstract class Manager {
6.
7. protected String name;
8. // 上级
9. protected Manager superior;
10.
11. public Manager(String name){
12. this.name = name;
13. }
14.
15. // 设置上级
16. public void setSuperior(Manager superior){
17. this.superior = superior;
18. }
19.
20. // 申请请求
21. public abstract void requestApplications(Request request);
22.
23. }
24.
1. /**
2. * 经理
3. * Created by callmeDevil on 2019/12/14.
4. */
5. public class CommonManager extends Manager {
6.
7. public CommonManager(String name) {
8. super(name);
9. }
10.
11. @Override
12. public void requestApplications(Request request) {
13. // 经理的权限可以批准2天内的假期
14. if ("请假".equals(request.getRequestType()) && request.getNumber() <= 2) {
15. System.out.println(String.format("%s : %s 数量%s 被批准", name, request.getRequestContent(), request.getNumber()));
16. } else {
17. // 其余申请转交上级
18. if (superior != null) {
19. superior.requestApplications(request);
20. }
21. }
22. }
23.
24. }
25.
1. /**
2. * 总监
3. * Created by callmeDevil on 2019/12/14.
4. */
5. public class Majordomo extends Manager {
6.
7. public Majordomo(String name) {
8. super(name);
9. }
10.
11. @Override
12. public void requestApplications(Request request) {
13. // 总监的权限可以批准5天内的假期
14. if ("请假".equals(request.getRequestType()) && request.getNumber() <= 5) {
15. System.out.println(String.format("%s : %s 数量%s 被批准", name, request.getRequestContent(), request.getNumber()));
16. } else {
17. // 其余申请转交上级
18. if (superior != null) {
19. superior.requestApplications(request);
20. }
21. }
22. }
23.
24. }
25.
1. /**
2. * 总经理
3. * Created by callmeDevil on 2019/12/14.
4. */
5. public class GeneralManager extends Manager {
6.
7. public GeneralManager(String name) {
8. super(name);
9. }
10.
11. @Override
12. public void requestApplications(Request request) {
13. // 总经理可以批准任意天的假期
14. if ("请假".equals(request.getRequestType())) {
15. System.out.println(String.format("%s : %s 数量%s 被批准", name, request.getRequestContent(), request.getNumber()));
16. }
17. // 加薪在500内,没问题
18. else if ("加薪".equals(request.getRequestType()) && request.getNumber() <= 500) {
19. System.out.println(String.format("%s : %s 数量%s 被批准", name, request.getRequestContent(), request.getNumber()));
20. }
21. // 加薪超过500要考虑一下
22. else if ("加薪".equals(request.getRequestType()) && request.getNumber() > 500) {
23. System.out.println(String.format("%s : %s 数量%s 再说吧", name, request.getRequestContent(), request.getNumber()));
24. }
25. }
26.
27. }
28.
1. /**
2. * 申请类
3. * Created by callmeDevil on 2019/12/14.
4. */
5. public class Request {
6.
7. // 申请级别
8. private String requestType;
9. // 申请内容
10. private String requestContent;
11. // 数量
12. private int number;
13.
14. // 省略get set
15. }
16.
1. public class Test {
2. public static void main(String[] args) {
3. CommonManager commonManager = new CommonManager("中将");
4. Majordomo majordomo = new Majordomo("大将");
5. GeneralManager generalManager = new GeneralManager("元帅");
6. // 设置上级
7. commonManager.setSuperior(majordomo);
8. majordomo.setSuperior(generalManager);
9.
10. Request request = new Request();
11. request.setRequestType("请假");
12. request.setRequestContent("不给请假我不干了");
13. request.setNumber(1);
14. commonManager.requestApplications(request); // 客户端的申请都是由经理发起的,但实际上决策是谁,客户端不知道
15.
16. Request request2 = new Request();
17. request2.setRequestType("请假");
18. request2.setRequestContent("不给请假我不干了");
19. request2.setNumber(4);
20. commonManager.requestApplications(request2);
21.
22. Request request3 = new Request();
23. request3.setRequestType("加薪");
24. request3.setRequestContent("不给加薪我不干了");
25. request3.setNumber(500);
26. commonManager.requestApplications(request3);
27.
28. Request request4 = new Request();
29. request4.setRequestType("加薪");
30. request4.setRequestContent("不给加薪我不干了");
31. request4.setNumber(1000);
32. commonManager.requestApplications(request4);
33. }
34. }
35.
运行结果
1. 中将 : 不给请假我不干了 数量1 被批准
2. 大将 : 不给请假我不干了 数量4 被批准
3. 元帅 : 不给加薪我不干了 数量500 被批准
4. 元帅 : 不给加薪我不干了 数量1000 再说吧
5.
Pass:以上纯属个人理解~~如果发现有错或是心存建议意见等,欢迎大家评论或联系~(# ゚Д゚)~祝大家身体健康学习进步工作顺利生活愉快!
版权归 callmeDevil 所有,如需转载请标注转载来源
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥