责任链模式

begin 2021年12月11日20:47:41

责任链模式

定义

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 objects and pass the request along the chain until an object handles it. ——《Design Patterns: Elements of Reusable Object-Oriented Software》 

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将接收对象连城一条链,并沿着链传递该请求,直到有一个对象处理它为止。 ——《设计模式:可复用面向对象软件的基础》

责任链模式是一种行为型设计模式。

使用场景

在以下场景下使用责任链模式:

  • 有多个对象处理一个请求时,且处理者不知道处理优先级。
  • 你想让多个处理者处理一个请求,不需要知道具体处理者。
  • 处理请求的对象集合应该是自动确定的。

总的来说,就是处理请求的处理者有多个,但是客户端只知道其中一个,其他都是主动排好队,等着处理请求的。

图示

责任链结构图:

责任链模式

角色

客户端(Client):

  • 初始化请求给责任链上的一个具体处理者

抽象处理者(Handler):

  • 定义一个处理请求的接口
  • 设置下一位处理者的引用

具体处理者(Handler):

  • 处理它负责的请求
  • 如果具体处理者可以处理请求,就处理;否则,将请求交给它的继承者

请求(Request):

  • 封装了需要处理的信息,传递给处理者进行处理。

代码示例

// 抽象处理者类 abstract class Handler {     protected Handler successor;      public void setSuccessor(Handler successor) {         this.successor = successor;     }      public abstract void handleRequest(Request request); }  // 具体处理者类A class HandlerA extends Handler {     public void handleRequest(Request request) {         if (request.getType() == RequestType.TYPE_A) {             // 处理请求         } else if (successor != null) {             successor.handleRequest(request);         }     } }  // 具体处理者类B class HandlerB extends Handler {     public void handleRequest(Request request) {         if (request.getType() == RequestType.TYPE_B) {             // 处理请求         } else if (successor != null) {             successor.handleRequest(request);         }     } }  // 请求类 class Request {     private RequestType type;      public Request(RequestType type) {         this.type = type;     }      public RequestType getType() {         return type;     } }  // 请求类型枚举类 enum RequestType {     TYPE_A, TYPE_B }  // 使用示例 public class Client {     public static void main(String[] args) {         Handler handlerA = new HandlerA();         Handler handlerB = new HandlerB();         handlerA.setSuccessor(handlerB);          Request request1 = new Request(RequestType.TYPE_A);         handlerA.handleRequest(request1);          Request request2 = new Request(RequestType.TYPE_B);         handlerA.handleRequest(request2);     } } 

故事版代码示例

产房内哇的一声啼哭,你已经降临这个世界。

你慢慢长大,学习,工作,结婚生子。

爸妈永远是你的支持。

public interface Support {     void setSuccessor(Support successor);     void handle(You you); }  public class MaMa implements Support {     private String name = "妈妈";     private Support successor;     @Override     public void setSuccessor(Support successor) {         this.successor = successor;     }      @Override     public void handle(You you) {         if (you.getObtainType() == ObtainType.NAME) {             System.out.println(name + ":怀孕了,起个好听的名字");             successor.handle(you);         } else if (you.getObtainType() == ObtainType.BORN) {             System.out.println(name + ":十月怀胎,你出生了");             successor.handle(you);         } else if (you.getObtainType() == ObtainType.EDUCATION) {             System.out.println(name + ":十六年努力工作,提供给你最好的教育");             successor.handle(you);         } else if (you.getObtainType() == ObtainType.WORK) {             System.out.println(name + ":给你鼓励");             successor.handle(you);         } else if (you.getObtainType() == ObtainType.MARRIAGE) {             System.out.println(name + ":倾尽所有买房买车");             successor.handle(you);         }     } }  public class BaBa implements Support{     private String name = "爸爸";     private Support successor;     @Override     public void setSuccessor(Support successor) {         this.successor = successor;     }      @Override     public void handle(You you) {         if (you.getObtainType() == ObtainType.NAME) {             System.out.println(name + ":让岳父起个好听的名字");             successor.handle(you);         } else if (you.getObtainType() == ObtainType.BORN) {             System.out.println(name + ":高兴");             successor.handle(you);         } else if (you.getObtainType() == ObtainType.EDUCATION) {             System.out.println(name + ":十六年和妈妈一起努力工作,提供给你最好的教育");             successor.handle(you);         } else if (you.getObtainType() == ObtainType.WORK) {             System.out.println(name + ":给你指导");             successor.handle(you);         } else if (you.getObtainType() == ObtainType.MARRIAGE) {             System.out.println(name + ":和妈妈一起倾尽所有买房买车");             successor.handle(you);         }     } }  public class WaiGong implements Support {     private String name = "外公";     private Support successor;     @Override     public void setSuccessor(Support successor) {         this.successor = successor;     }      @Override     public void handle(You you) {         if (you.getObtainType() == ObtainType.NAME) {             System.out.println(name + ":名叫晓月");         } else if (you.getObtainType() == ObtainType.BORN) {             System.out.println(name + ":你们多了一份责任");         } else if (you.getObtainType() == ObtainType.EDUCATION) {             System.out.println(name + ":暑假的大热天的扇子,冬天热乎的番薯");         } else if (you.getObtainType() == ObtainType.WORK) {             System.out.println(name + ":你很努力,也很棒");         } else if (you.getObtainType() == ObtainType.MARRIAGE) {             System.out.println(name + ":开心看到你结婚");         }     } }  public class Family {     public static void main(String[] args) {         // 爸爸         BaBa baBa = new BaBa();         // 妈妈         MaMa maMa = new MaMa();         // 外公         WaiGong waiGong = new WaiGong();          // 结婚,爸爸成了妈妈的支持         maMa.setSuccessor(baBa);         // 外公对爸爸说,我们是一家人,我可以成为你的支持         baBa.setSuccessor(waiGong);         // 妈妈怀孕了         You you = new You();         you.setAge(-1);         // 你一生的支持,103岁die         while(you.getAge() < 103) {             // 你主观或者客观提出了请求             produceRequest(you);             // 家人支持处理你的请求             handleRequest(you, maMa);             // 下一重要阶段             setNextAge(you);         }      }      private static void setNextAge(You you) {         if (you.getAge() == -1) {             you.setAge(0);         } else if (you.getAge() == 0) {             you.setAge(3);         } else if (you.getAge() >= 3 && you.getAge() < 22) {             you.setAge(22);         } else if (you.getAge() >= 22 && you.getAge() < 24) {             you.setAge(24);         } else if (you.getAge() == 24) {             you.setAge(103);         }     }      private static void handleRequest(You you, MaMa maMa) {         maMa.handle(you);     }      private static void produceRequest(You you) {         if (you.getAge() == -1) {             you.setObtainType(ObtainType.NAME);         } else if (you.getAge() == 0) {             you.setObtainType(ObtainType.BORN);         } else if (you.getAge() >= 3 && you.getAge() < 22) {             you.setObtainType(ObtainType.EDUCATION);         } else if (you.getAge() >= 22 && you.getAge() < 24) {             you.setObtainType(ObtainType.WORK);         } else if (you.getAge() == 24) {             you.setObtainType(ObtainType.MARRIAGE);         }     } } 

代码示例结果:

责任链模式

优点

责任链模式的优点在于它可以将请求的处理分散到多个对象中,降低了对象之间的耦合度。同时,责任链模式也比较灵活,可以动态地组织处理者链,以满足不同的需求。

缺点

但是责任链模式也有一些缺点。首先,由于每个处理者都要处理请求,因此处理者链过长或者处理者数量过多可能会影响性能。其次,如果处理者链没有被正确组织,可能会导致请求无法得到处理或者处理不当的情况发生。

总结

当你需要多个处理者处理一个请求,并想任意组合处理者时,可以使用责任链模式。该模式具有降低耦合,以及灵活组织处理者的优点。

2023年03月19日17:36:53

发表评论

评论已关闭。

相关文章