这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
我要学会设计模式之责任链模式
定义:多个对象均有机会处理请求,从而解除发送者和接受者之间的耦合关系。这些对象连接成为“链式结构”,每个节点转发请求,直到有对象处理请求为止。
核心思想:请求者不必知道是谁哪个节点对象处理的请求。如果当前不符合终止条件,那么把请求转发给下一个节点处理。
什么是“责任链模式”?
责任链模式定义:多个对象均有机会处理请求,从而解除发送者和接受者之间的耦合关系。这些对象连接成为“链式结构”,每个节点转发请求,直到有对象处理请求为止。
其核心思想就是:请求者不必知道是谁哪个节点对象处理的请求。如果当前不符合终止条件,那么把请求转发给下一个节点处理。
而当需求具有“传递”的性质时(代码中其中一种体现就是:多个if、else if、else if、else嵌套),就可以考虑将每个分支拆分成一个节点对象,拼接成为责任链。
优点与代价
优点:
- 可以根据需求变动,任意向责任链中添加 / 删除节点对象
- 没有固定的“开始节点”,可以从任意节点开始
代价:责任链最大的代价就是每个节点带来的多余消耗。当责任链过长,很多节点只有传递的作用,而不是真正地处理逻辑。
什么时候需要用责任链模式?
系统设计的时候,注意区分主次就好,即哪部分是核心流程,哪部分是辅助流程,辅助流程是否有N多if...if...if...的场景,如果是且每个if都有一个统一的抽象,那么抽象辅助流程,把每个if作为一个责任对象进行链式调用,优雅实现,易复用可扩展。
代码实现
为了方便演示,模拟常见的“日志打印”场景。模拟了 3 种级别的日志输出:
LogHandler: 普通日志WarnHandler:警告日志ErrorHandler:错误日志
首先我们会构造“责任链”:LogHandler -> WarnHandler -> ErrorHandler。LogHandler作为链的开始节点。
如果是普通日志,那么就由 LogHandler 处理,停止传播;如果是 Warn 级别的日志,那么 LogHandler 就会自动向下传递,WarnHandler 接收到并且处理,停止传播;Error 级别日志同理。
public class Study {
public void study(PreparationList preparationList) {
if (preparationList.isWashHair()) {
System.out.println("洗脸");
}
if (preparationList.isWashHair()) {
System.out.println("洗头");
}
if (preparationList.isHaveBreakfast()) {
System.out.println("吃早餐");
}
System.out.println("我可以去上学了!");
}
}
public abstract class AbstractPrepareFilter {
private AbstractPrepareFilter nextPrepareFilter;
public AbstractPrepareFilter(AbstractPrepareFilter nextPrepareFilter) {
this.nextPrepareFilter = nextPrepareFilter;
}
public void doFilter(PreparationList preparationList, Study study) {
prepare(preparationList);
if (nextPrepareFilter == null) {
study.study();
} else {
nextPrepareFilter.doFilter(preparationList, study);
}
}
public abstract void prepare(PreparationList preparationList);
}
public class WashFaceFilter extends AbstractPrepareFilter {
public WashFaceFilter(AbstractPrepareFilter nextPrepareFilter) {
super(nextPrepareFilter);
}
@Override
public void prepare(PreparationList preparationList) {
if (preparationList.isWashFace()) {
System.out.println("洗脸");
}
}
}
\