实例:烹饪。周六中午一个人吃饭,我就煮了面和一个番茄蛋汤。让我们来看看煮面和做汤的流程:
- 煮面的流程:烧水 --> 煮,等会沸腾之后,就把面放进沸腾的水中煮熟。
- 做番茄蛋汤的流程:处理鸡蛋 --> 处理番茄 --> 烧水 --> 煮,先处理鸡蛋和番茄,同时可以把水烧开,最后将鸡蛋和番茄放入热水中煮
用 if-else 来实现周六的午饭:
if (烹饪面) {
烧水;
放入面;
煮;
} else if (烹饪番茄鸡蛋汤) {
烧水;
处理鸡蛋和番茄;
煮;
}
如果我又想做个菜,番茄炒鸡蛋呢,又得在原来的代码上做改动,同时处理鸡蛋和处理番茄的流程又得重新写一遍。
if (烹饪面) {
烧水;
放入面;
煮;
} else if (烹饪番茄鸡蛋汤) {
烧水;
处理鸡蛋;
处理番茄;
煮;
} else if (烹饪番茄炒鸡蛋) {
处理鸡蛋;
处理番茄;
炒;
}
同时,如果我忘记放盐了,需要在每一个if-else 中再加入放盐的流程,这样对代码的入侵性非常大。
所以,总结一下上面做饭流程的缺点是:
- 违反单一职责的原则:同一个方法里面太多处理逻辑,不利于复用代码。
- 违反开闭原则:增加一种菜,就需要增加一个 else-if,改进烹饪方法,就需要改动原来的代码。
用职责链模式改进
概念
责任链模式(也称职责链):用于改进用户过程。所谓责任,可以理解为责任分担,每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围。
责任链模式是一种对象行为型模式,其主要优点如下:
- 降低了对象之间的耦合度:该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
- 增强了系统的可扩展性:可以根据需要增加新的请求处理类,满足开闭原则。
- 增强了给对象指派职责的灵活性:当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
- 简化了对象之间的连接:每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,请求会自动进行传递。所以责任链将请求的发送者和请求的处理者解耦了。
开始动手
首先定义一个职责:在这里也就是一个基本处理的步骤,比如:烧水,煮,处理鸡蛋,处理番茄等,把做饭当做一个流程,对这些处理步骤进行组合,就能够达到复用的目的。
/**
* @author tuhao
* @date 2021/1/24 4:29 下午
* @desc 烹饪
* 煮面的流程:烧水 --> 煮,等会沸腾之后,就把面放进沸腾的水中煮熟。
* 做番茄蛋汤的流程:处理鸡蛋 --> 处理番茄 --> 烧水 --> 煮,先处理鸡蛋和番茄,同时可以把水烧开,最后将鸡蛋和番茄放入热水中煮
*/
public class CookHandler {
protected CookHandler next;
/** 步骤名称 **/
protected String dealName;
/**处理请假的请求,子类实现*/
protected void handleRequest(CookHandlerRequest request) {
}
/** 设置下一个处理节点 **/
protected void setNext(CookHandler handler) {
this.next = handler;
}
/** 获取下一个处理节点 **/
protected CookHandler getNext() {
return this.next;
}
}
实现煮:
/**
* @author tuhao
* @date 2021/1/24 4:44 下午
* @desc 煮
*/
public class