当前位置:   article > 正文

设计模式之责任链模式_责任链模式翻译

责任链模式翻译

本文参考:

https://www.cnblogs.com/aeolian/p/8888958.html

https://www.cnblogs.com/fengyumeng/p/10839570.html

定义

责任链模式(Chain of Responsibility Pattern)是一种常见的行为模式。

责任链模式英文原话是:Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving object and pass the request along the chain until an object handles it.

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

责任链模式的重点在“链上”,由一条链去处理相似的请求,在链中决定谁来处理这个请求,并返回相应的结果。

角色:

抽象处理者(Handler)角色:该角色对请求进行抽象,并定义一个方法来设定和返回对下一个处理者的引用。

具体处理者(Concrete Handler):该角色接到请求后,可以选择将请求处理掉,或者将请求传给下一个处理者。由于具体处理者持有对下一个处理者的引用,因此,如果需要,处理者可以访问下一个处理者。

简单实例

如果在公司里,因为病假要请一个月的假需要经过组长、经理等好几轮的审核签字,这跟咱们的责任链模式非常相似,现以请假为例:

         角色1:请假条,其实可以理解成请假人,因为请假条上自然有请假人信息。

  角色2:领导人,小组长、部门经理、总经理都是审批人。

  动作:领导人审批请假条。

流程如下:

请假条抽象:

  1. public interface ILeave {
  2. String getName();//请假人姓名
  3. int getNum();//请假天数
  4. String getContent();//请假条内容
  5. }

请假条实现:

  1. public class Leave implements ILeave{
  2. private String name;//姓名
  3. private int num;//请假天数
  4. private String content;//请假内容
  5. public Leave(String name, int num, String content) {
  6. this.name = name;
  7. this.num = num;
  8. this.content = content;
  9. }
  10. public String getName() {
  11. return name;
  12. }
  13. public int getNum() {
  14. return num;
  15. }
  16. public String getContent() {
  17. return content;
  18. }
  19. }

领导人抽象:

  1. public interface IHandler {
  2. void handleLeave(ILeave leave);//处理请假条
  3. }

领导人实现:

  1. public class GroupLeader implements IHandler {
  2. @Override
  3. public void handleLeave(ILeave leave) {
  4. System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
  5. System.out.println("小组长审批:同意。");
  6. }
  7. }
  8. public class Manager implements IHandler {
  9. @Override
  10. public void handleLeave(ILeave leave) {
  11. System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
  12. System.out.println("部门经理审批:同意。");
  13. }
  14. }
  15. public class BigManager implements IHandler {
  16. @Override
  17. public void handleLeave(ILeave leave) {
  18. System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
  19. System.out.println("总经理审批:同意。");
  20. }
  21. }

客户端实现:

  1. public static void main(String[] args) {
  2. //请假条来一张
  3. ILeave leave = new Leave("小花",5,"身体不适");
  4. //小组长第一个审批
  5. IHandler groupLeader = new GroupLeader();
  6. groupLeader.handleLeave(leave);
  7. if(leave.getNum() >= 3){
  8. IHandler manager = new Manager();
  9. manager.handleLeave(leave);
  10. }
  11. if(leave.getNum() >= 7){
  12. IHandler bigManager = new BigManager();
  13. bigManager.handleLeave(leave);
  14. }
  15. }

输出:

小花请假5天,身体不适。
小组长审批:同意。
小花请假5天,身体不适。
部门经理审批:同意。

这个程序是有问题,如果公司修改请假制度,一个月以上的请假需要老板审核签字,就得在客户端实现方法再写个if语句,这显然是有问题的。正确的逻辑应该是什么样的呢? 应该是小花递了请假条之后,就只需要等结果即可,而不是找了这个审批,回来后又跑去找那个审批。

优化:

请假条抽象:

  1. public interface ILeave {
  2. String getName();//请假人姓名
  3. int getNum();//请假天数
  4. String getContent();//请假条内容
  5. }

请假条:

  1. public class Leave implements ILeave{
  2. private String name;//姓名
  3. private int num;//请假天数
  4. private String content;//请假内容
  5. public Leave(String name, int num, String content) {
  6. this.name = name;
  7. this.num = num;
  8. this.content = content;
  9. }
  10. public String getName() {
  11. return name;
  12. }
  13. public int getNum() {
  14. return num;
  15. }
  16. public String getContent() {
  17. return content;
  18. }
  19. }

领导人抽象:

  1. public abstract class Handler {
  2. protected final static int NUM_ONE = 1;
  3. protected final static int NUM_THREE = 3;
  4. protected final static int NUM_SEVEN = 7;
  5. //该领导处理的请假天数区间
  6. private int numStart = 0;
  7. private int numEnd = 0;
  8. //领导上面还有领导
  9. private Handler nextHandler;
  10. //设置请假天数范围 上不封顶
  11. public Handler(int numStart) {
  12. this.numStart = numStart;
  13. }
  14. //设置请假天数范围
  15. public Handler(int numStart, int numEnd) {
  16. this.numStart = numStart;
  17. this.numEnd = numEnd;
  18. }
  19. //设置上级领导
  20. public void setNextHandler(Handler nextHandler){
  21. this.nextHandler = nextHandler;
  22. }
  23. //提交请假条
  24. public final void submit(ILeave leave){
  25. if(0 == this.numStart){
  26. return;
  27. }
  28. //如果请假天数达到该领导者的处理要求
  29. if(leave.getNum() >= this.numStart){
  30. this.handleLeave(leave);
  31. //如果还有上级 并且请假天数超过了当前领导的处理范围
  32. if(null != this.nextHandler && leave.getNum() > numEnd){
  33. this.nextHandler.submit(leave);//继续提交
  34. }
  35. }
  36. }
  37. //各级领导处理请假条方法
  38. protected abstract void handleLeave(ILeave leave);
  39. }

领导人实例:

  1. public class GroupLeader extends Handler {
  2. public GroupLeader() {
  3. //小组长处理1-3天的请假
  4. super(Handler.NUM_ONE, Handler.NUM_THREE);
  5. }
  6. @Override
  7. protected void handleLeave(ILeave leave) {
  8. System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
  9. System.out.println("小组长审批:同意。");
  10. }
  11. }
  12. public class Manager extends Handler {
  13. public Manager() {
  14. //部门经理处理3-7天的请假
  15. super(Handler.NUM_THREE, Handler.NUM_SEVEN);
  16. }
  17. @Override
  18. protected void handleLeave(ILeave leave) {
  19. System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
  20. System.out.println("部门经理审批:同意。");
  21. }
  22. }
  23. public class BigManager extends Handler {
  24. public BigManager() {
  25. //部门经理处理7天以上的请假
  26. super(Handler.NUM_SEVEN);
  27. }
  28. @Override
  29. protected void handleLeave(ILeave leave) {
  30. System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
  31. System.out.println("总经理审批:同意。");
  32. }
  33. }

客户端:

  1. public static void main(String[] args) {
  2. //请假条来一张
  3. ILeave leave = new Leave("小花",5,"身体不适");
  4. //各位领导
  5. Handler groupLeader = new GroupLeader();
  6. Handler manager = new Manager();
  7. Handler bigManager = new BigManager();
  8. groupLeader.setNextHandler(manager);//小组长的领导是部门经理
  9. manager.setNextHandler(bigManager);//部门经理的领导是总经理
  10. //之所以在这里设置上级领导,是因为可以根据实际需求来更改设置,如果实战中上级领导人都是固定的,则可以移到领导实现类中。
  11. //提交申请
  12. groupLeader.submit(leave);
  13. }

输出:

小花请假5天,身体不适。
小组长审批:同意。
小花请假5天,身体不适。
部门经理审批:同意。

优点

  • 责任链模式将请求和处理分开,请求者不知道是谁处理的,处理者可以不用知道请求的全貌。
  • 提高系统的灵活性。

缺点

  • 降低程序的性能。每个请求都是从链头遍历到链尾,当链比较长的时候,性能会大幅下降。
  • 不易于调试。由于该模式采用了类似递归的方式,调试的时候逻辑比较复杂。

应用场景

责任链模式是一种常见的模式,Struts2的核心控件FilterDispatcher是一个Servlet过滤器,该控件就是采用责任链模式,可以对用户请求进行层层过滤处理。责任链模式在实际项目中的使用比较多,其典型的应用场景如下:

  • 一个请求需要一系列的处理工作。
  • 业务流的处理,例如文件审批。
  • 对系统进行扩展补充。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/497907
推荐阅读
相关标签
  

闽ICP备14008679号