职责链模式

墨蓝 2024-04-19 07:17 95阅读 0赞

前言

项目中有考勤请假审批这个模块,可以用到职责链模式。

过程

请一天假,请示小组长,请三天假,请示项目经理,请五天及五天以上的假,请示CTO。

提出请假的人便是Client,而组长、经理、CTO三者其实是同一类人,即都是请求处理者(ConcreteHandler),而他们都是抽象的处理者(Handler)的子类。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25pbmdtZW5nYmFieQ_size_16_color_FFFFFF_t_70

  1. Client: 调用者;
  2. Request: 请求体,用于封装一些请求的信息,有时候判断的因素不只是一个;
  3. Response: 结果实体,消息处理完封装的结果类;
  4. Handler: 处理请求的实体类;
  5. Level: 等级类,用于保存当前等级的一些消息,如果逻辑简单可以和Request类合并;

编码时刻

Handler:

  1. public abstract class Handler {
  2. //指向下一个处理类
  3. private Handler nextHandler;
  4. public final Response handleMessage(Request request) {
  5. Response response = null;
  6. //判断是否是自己的处理等级
  7. if (request.getLevel().getDay() <= this.getHandlerLevel().getDay()) {
  8. //是自己的处理等级,就将其进行处理
  9. response = this.echo(request);
  10. } else {
  11. //如果还有下一个handler
  12. if (this.nextHandler != null) {
  13. //如果有就让下一个handler进行处理
  14. response = this.nextHandler.handleMessage(request);
  15. } else {
  16. //没有适当的处理者,由调用者自己处理,获取不处理
  17. }
  18. }
  19. return response;
  20. }
  21. /**
  22. * @Description 设置下一个handler处理类
  23. * @version
  24. */
  25. public void setNextHandler(Handler nextHandler) {
  26. this.nextHandler = nextHandler;
  27. }
  28. /**
  29. * @Description 模版方法,由子类决定当前实现的实体类是什么等级
  30. * @version
  31. */
  32. protected abstract Level getHandlerLevel();
  33. /**
  34. * @Description 对任务的具体处理操作
  35. * @version
  36. */
  37. protected abstract Response echo(Request request);
  38. }
  39. public class CTOHandler extends Handler {
  40. @Override
  41. public Level getHandlerLevel() {
  42. return new Level("技术总监", 5);
  43. }
  44. @Override
  45. public Response echo(Request request) {
  46. return new Response("我是"+getHandlerLevel().getLevelName()+",我准了!");
  47. }
  48. }
  49. public class ManagerHandler extends Handler {
  50. @Override
  51. public Level getHandlerLevel() {
  52. return new Level("经理",3);
  53. }
  54. @Override
  55. public Response echo(Request request) {
  56. return new Response("我是"+getHandlerLevel().getLevelName()+",我准了!");
  57. }
  58. }
  59. public class TeamLeaderHandler extends Handler {
  60. @Override
  61. public Level getHandlerLevel() {
  62. return new Level("组长", 1);
  63. }
  64. @Override
  65. public Response echo(Request request) {
  66. return new Response("我是"+getHandlerLevel().getLevelName()+",我准了!");
  67. }
  68. }

在Handler中,由handleMessage方法进行判断是否交由当前的handler进行处理,在这个抽象类中使用了模版方法(getHandlerLevel和echo),将Handler的等级和处理逻辑延迟到子类进行处理。所以子类的handler只需要处理好当前自己等级的逻辑即可,然后基类的handler做好链的调用逻辑处理(即什么情况交由当前handler,什么情况传递下一个处理),最后等待拼装成链给到用户(即例子中的请假人)使用。
接下来看下请求类、结果类、等级类:

  1. public class Request {
  2. private Level mLevel;
  3. public Request(Level mLevel) {
  4. this.mLevel = mLevel;
  5. }
  6. public Level getLevel() {
  7. return this.mLevel;
  8. }
  9. }
  10. public class Response {
  11. private String content;
  12. public Response(String content) {
  13. this.content = content;
  14. }
  15. public String getContent() {
  16. return content;
  17. }
  18. public void setContent(String content) {
  19. this.content = content;
  20. }
  21. }
  22. public class Level {
  23. private String levelName;
  24. private int day;
  25. public Level(String levelName, int day) {
  26. this.levelName = levelName;
  27. this.day = day;
  28. }
  29. public Level(int day) {
  30. this.day = day;
  31. }
  32. public String getLevelName() {
  33. return levelName;
  34. }
  35. public void setLevelName(String levelName) {
  36. this.levelName = levelName;
  37. }
  38. public int getDay() {
  39. return day;
  40. }
  41. public void setDay(int day) {
  42. this.day = day;
  43. }
  44. }

这几个类比较简单,只是常规的bean,在真正的使用中,可能会减少也有可能会增多,这个视情况而定。
最后就是使用职责链了,这里使用了一个ResponChainHelper辅助类,进行职责链的拼装,让client无需知道拼装过程。从client类中,可看到,这时只需要获取到职责链的handler,实例化一个request,交由handler处理即可,至于谁处理,对于用于来说是透明的。

  1. public class ResponChainHelper {
  2. public static Handler getResChain() {
  3. Handler ctoHandler = new CTOHandler();
  4. Handler managerHandler = new ManagerHandler();
  5. Handler teamLeaderHandler = new TeamLeaderHandler();
  6. teamLeaderHandler.setNextHandler(managerHandler);
  7. managerHandler.setNextHandler(ctoHandler);
  8. return teamLeaderHandler;
  9. }
  10. }
  11. public class Client {
  12. public static void main(String[] args) {
  13. Handler handler = ResponChainHelper.getResChain();
  14. System.out.println("我想要请一天假:");
  15. Request request1 = new Request(new Level(1));
  16. Response response1 = handler.handleMessage(request1);
  17. System.out.println(response1.getContent());
  18. System.out.println("我想要请三天假:");
  19. Request request2 = new Request(new Level(3));
  20. Response response2 = handler.handleMessage(request2);
  21. System.out.println(response2.getContent());
  22. System.out.println("我想要请五天假:");
  23. Request request3 = new Request(new Level(5));
  24. Response response3 = handler.handleMessage(request3);
  25. System.out.println(response3.getContent());
  26. }
  27. }

如何扩展

如果此时,需求变动,需要增加一项:请假10天的需要CEO批准(这里只是打个比方,现实的CEO很忙不会有空管理这些事),只需要继承handler,然后编写自己需要处理的逻辑,最后在helper中加入到指责链,其余的所有代码都无需改动。

  1. public class CEOHandler extends Handler {
  2. @Override
  3. protected Level getHandlerLevel() {
  4. return new Level("CEO", 10);
  5. }
  6. @Override
  7. protected Response echo(Request request) {
  8. return new Response("我是" + getHandlerLevel().getLevelName() + ",我准了!");
  9. }
  10. }
  11. public class ResponChainHelper {
  12. public static Handler getResChain() {
  13. Handler ctoHandler = new CTOHandler();
  14. Handler managerHandler = new ManagerHandler();
  15. Handler teamLeaderHandler = new TeamLeaderHandler();
  16. Handler ceoHandler = new CEOHandler();
  17. teamLeaderHandler.setNextHandler(managerHandler);
  18. managerHandler.setNextHandler(ctoHandler);
  19. ctoHandler.setNextHandler(ceoHandler);
  20. return teamLeaderHandler;
  21. }
  22. }

借鉴:https://www.jianshu.com/p/d20a314039ef

发表评论

表情:
评论列表 (有 0 条评论,95人围观)

还没有评论,来说两句吧...

相关阅读

    相关 职责模式

    前言 项目中有考勤请假审批这个模块,可以用到职责链模式。 过程 请一天假,请示小组长,请三天假,请示项目经理,请五天及五天以上的假,请示CTO。 提出请假的...

    相关 职责模式

    > 将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。 经典实现方式一

    相关 职责模式

    1.职责链模式概述 很多情况下,在一个软件系统中可以处理某个请求的对象不止一个,例如SCM系统中的采购单审批,主任、副董事长、董事长和董事会都可以处理采购单,他们可以构成

    相关 职责模式

    前言   职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿

    相关 职责模式

    虚类中包含一个自己的同类对象叫nextChain。重载方法中判断是否是自己应该处理的,并转给nextChain.这样一层一层。。。。 可以用管理类+数组来代替。 当然很明显

    相关 设计模式----职责模式

    今天,我们来学习学习职责链模式,职责链模式,从字面上的意思还真的不好理解,我们要拆分来理解下,职责和链,职责不用解释了就是自己需要做的事,那么链呢,何为链,就是锁链嘛!我...