祝大家1024节日快乐,致敬一线编程工作者,学习者。
说明
责任链模式(Chain of Responsibility Pattern)属于行为型模式,它为请求创建了一个处理者对象的链,请求将在这个对象链上被处理,责任链模式并不要求请求一定要在某一个处理者上被处理完,简单的说,就是链上的处理者都可能处理请求的一部分,该模式可以有效的解耦请求的请求者和处理者。
应用场景
- 一个请求需要一系列的处理工作。
- 业务流的处理,例如文件审批。
- 对系统进行扩展补充。
模式特征
角色 | 说明 | 举栗 |
---|---|---|
抽象处理者(Handler) | 该角色对请求进行抽象,并定义一个方法来设定和返回对下一个处理者的引用 | Handler |
具体处理者(Concrete Handler) | 该角色接到请求后,可以选择将请求处理掉,或者将请求传给下一个处理者。由于具体处理者持有对下一个处理者的引用,因此,如果需要,处理者可以访问下一个处理者 | OneHandler、TwoHandler、ThreeHandler |
代码实现
- 抽象处理者
public abstract class Handler {
protected Handler nextHandler;
public Handler getNextHandler() {
return nextHandler;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handler(int type);
}
- 具体处理者一
public class OneHandler extends Handler {
@Override
public void handler(int type) {
if (type == 1){
System.out.println(this.getClass().getName() + "处理了类型一的消息");
} else {
System.out.println(this.getClass().getName() + "无法处理该消息");
}
if (nextHandler != null){
nextHandler.handler(type);
}
}
}
- 具体处理者二
public class TwoHandler extends Handler {
@Override
public void handler(int type) {
if (type == 2){
System.out.println(this.getClass().getName() + "处理了类型二的消息");
} else {
System.out.println(this.getClass().getName() + "无法处理该消息");
}
if (nextHandler != null){
nextHandler.handler(type);
}
}
}
- 具体处理者三
public class ThreeHandler extends Handler {
@Override
public void handler(int type) {
if (type == 3){
System.out.println(this.getClass().getName() + "处理了类型三的消息");
} else {
System.out.println(this.getClass().getName() + "无法处理该消息");
}
if (nextHandler != null){
nextHandler.handler(type);
}
}
}
- 客户端测试
public class Client {
public static void main(String[] args) {
OneHandler oneHandler = new OneHandler();
TwoHandler twoHandler = new TwoHandler();
ThreeHandler threeHandler = new ThreeHandler();
oneHandler.setNextHandler(twoHandler);
twoHandler.setNextHandler(threeHandler);
oneHandler.handler(3);
}
}
- 结果
cn.itoak.design.pattern.behavior.chain.of.responsibility.OneHandler无法处理该消息
cn.itoak.design.pattern.behavior.chain.of.responsibility.TwoHandler无法处理该消息
cn.itoak.design.pattern.behavior.chain.of.responsibility.ThreeHandler处理了类型三的消息
优缺点
优点
- 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和处理者也无须拥有对方的明确信息。
- 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
- 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
- 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
- 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
缺点
- 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
- 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
- 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。
写在最后
责任链模式的核心在于链,至于怎么实现这个链其实是很灵活的,其关键在于链首到链尾是可达的(非必达)。所以在代码实现中,只是简单的写了一下,并没有根据实际业务场景去实现,因为真正写业务代码的时候情况很复杂,所以需要读者多多思考,怎么去把代码写的严谨而优雅。