当前位置: 首页> 文旅> 艺术 > 15、设计模式之责任链模式

15、设计模式之责任链模式

时间:2025/7/11 0:25:31来源:https://blog.csdn.net/maligebazi/article/details/139109097 浏览次数:0次

责任链模式

顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

介绍

意图: 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

主要解决: 职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

何时使用: 在处理消息的时候以过滤很多道。

如何解决: 拦截的类都实现统一接口。

关键代码: Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。

应用实例:

  1. JS 中的事件冒泡。
  2. spring 拦截器。
  3. JAVA WEB 中 Apache Tomcat 对 Encoding 的处理
  4. Struts2 的拦截器

优点:

  1. 降低耦合度。它将请求的发送者和接收者解耦。
  2. 简化了对象。使得对象不需要知道链的结构。
  3. 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
  4. 增加新的请求处理类很方便。

缺点:

  1. 不能保证请求一定被接收。
  2. 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
  3. 可能不容易观察运行时的特征,有碍于除错。

使用场景:

  1. 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
  2. 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  3. 可动态指定一组对象处理请求。

注意事项: 在 JAVA WEB 中遇到很多应用。

主要涉及到以下几个核心角色:

抽象处理者(Handler):

定义一个处理请求的接口,通常包含一个处理请求的方法(如 handleRequest)和一个指向下一个处理者的引用(后继者)。
具体处理者(ConcreteHandler):

实现了抽象处理者接口,负责处理请求。如果能够处理该请求,则直接处理;否则,将请求传递给下一个处理者。
客户端(Client):
创建处理者对象,并将它们连接成一条责任链。通常,客户端只需要将请求发送给责任链的第一个处理者,无需关心请求的具体处理过程。

代码实现

以公司中的OA申请为例,有各种申请:请假、离职、团建、加班、购买设备等;不同申请需要的权限不一样,需要审批的人不一样。

定义申请类

/*** 申请*/
public class Petition {/*** 标题*/private String name;/*** 内容*/private String content;private Type type;/*** 申请人*/private String asker;public Petition(String name, String content, String asker, Type type) {this.name = name;this.content = content;this.asker = asker;this.type = type;}public String getName() {return name;}public String getContent() {return content;}public Type getType() {return type;}public String getAsker() {return asker;}public enum Type {/*** 请假*/LEAVE,/*** 加班*/OVERTIME,/*** 离职*/OFF_WORK,/*** 团建*/TRAVEL,/*** 购买设备*/BUY_EQUIPMENT,/*** 其他*/OTHER}
}

定义抽象职位


/***  职位*/
public abstract class Position {private Position nextPosition;public Position getNextPosition() {return this.nextPosition;}public Position nextPosition(Position nextPosition) {this.nextPosition = nextPosition;return this.nextPosition;}public abstract boolean handle(Petition petition);}

定义小组长,小组长只能审批类型为其他的申请

/*** 小组长*/
public class TeamLeader extends Position{@Overridepublic boolean handle(Petition petition) {if (petition.getType() == Petition.Type.OTHER){System.out.println("小组长审批" + petition.getName() + "通过");return true;}//小组长没有权限,提交给上一级审批return getNextPosition().handle(petition);}
}

定义经理,经理能够审批加班,请假,团建的申请

/*** 项目经理*/
public class Manager extends Position{@Overridepublic boolean handle(Petition petition) {if (petition.getType() == Petition.Type.OVERTIME|| petition.getType() == Petition.Type.LEAVE|| petition.getType() == Petition.Type.TRAVEL){System.out.println("项目经理审批" + petition.getName() + "通过");return true;}//项目经理没有权限,提交给上一级审批return getNextPosition().handle(petition);}
}

定义总经理,能够审批购买设备,离职的申请

/*** 总经理*/
public class GeneralManager extends Position{@Overridepublic boolean handle(Petition petition) {if (petition.getType() == Petition.Type.BUY_EQUIPMENT||petition.getType() == Petition.Type.OFF_WORK){System.out.println("总经理经理审批" + petition.getName() + "通过");return true;}else {System.out.println("总经理经理审批" + petition.getName() + "不通过");return false;}}
}

客户端

public class Client {public static void main(String[] args) {Manager manager = new Manager();TeamLeader teamLeader = new TeamLeader();GeneralManager generalManager = new GeneralManager();//小组长上级项目经理,项目经理上级总经理teamLeader.nextPosition(manager).nextPosition(generalManager);teamLeader.handle(new Petition("Buy equipment", "I need to buy a new computer", "Jim", Petition.Type.BUY_EQUIPMENT));teamLeader.handle(new Petition("Leave", "I need to leave", "Jim", Petition.Type.LEAVE));teamLeader.handle(new Petition("Overtime", "I need to work overtime", "Jim", Petition.Type.OVERTIME));teamLeader.handle(new Petition("Off work", "I need to go off work", "Jim", Petition.Type.OFF_WORK));teamLeader.handle(new Petition("Travel", "I need to travel", "Jim", Petition.Type.TRAVEL));teamLeader.handle(new Petition("Other", "I need to do something else", "Jim", Petition.Type.OTHER));}
}
关键字:15、设计模式之责任链模式

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: