初衷 :因架构(开发)场景(需求)而使用设计模式,莫为了使用设计模式而设计架构场景!
责任链模式?嗯哼… if else ?so easy 啊 ~
在我认为常用的if else处理就是责任链简化的一种形式,开发中还是用if else 多一些,架构级别可能用责任链模式更多一些 ~
设计模式共23种,分为三种类型
- 创建型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
- 结构型模式:代理模式、装饰模式、外观模式、享元模式、桥接模式、组合模式、适配器模式
- 行为型模式:观察者模式、策略模式、中介者模式、模版方法模式、命令模式、迭代器模式、职责链模式(责任链模式)、备忘录模式、解释器模式(Interpreter模式)、状态模式、访问者模式
基础概念
在此模式中客户(场景类)只负责将请求发送到责任链,无需关心请求的处理与传递过程,从而将请求的发送者和请求的处理者进行解耦
个人理解
在我学完责任链模式后,我觉得针对一些个人思考,值得一记,或许彼此会有一丢丢共鸣~
本应放于文末,但自我感觉比较有意义,所以在于其首,可在学习整篇之后,再来查看!!! 虽文字较多,但确是学习的意义所在 ~
-
我认为在客户类中我们发送请求之前,还需组装好责任链,也就是新建具体处理者和定义责任链的结构顺序,然后才可以发送请求(责任链创建好之后,一般都可以自定义到对应的节点进行操作,只不过此形态并非完整形态,除非跳过部分肯定不在责任范围内)
-
if else 和 责任链的区别到底在哪里?
这是我一直在思考的问题,我得出的结论是if else在开发中使用简单,一般多判断条件通过&活||拼接之后基本可以满足大部分需求,但是从本质来讲其实他本身就是责任链的一种体现,a不满足找b,b不满足找c,c要是也不满足,则该项责任链对此请求无效;但是为什么还会用到责任链呢?
我想应该是多重判断严重、内部实现复杂的场景,才会用到责任链这种模式,这样的话,在解耦的同时,每个人职责单一,层层处理,不过就是如果开发中要通用这种模式的话,还是不可取的,因为开中if else场景繁多,如果你在开发中都一直通过N个具体处理者才代替if else 那垃圾代码就太多了,所以只能针对部分非常复杂或核心的部分采用责任链机制
使用场景
- 需要动态指定或新增具体处理者
- 在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求
- 有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定
角色划分
抽象处理者
定义一个处理请求的接口(也可以是基类),内部包含处理者的后续连接,还有通用抽象处理方法
具体处理者
实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者
客户类(使用者:通用角色,可以不予理解)
创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程
优缺点
优点
- 扩展性、灵活性较强,可动态新增\删除具体处理者,同时执行顺序也可自行设置,满足开闭原则
- 降低了对象之间的耦合度,发送者和接收者无需明确具体方,也无需知道是哪一个对象处理了需求,更无需知道责任链结构
- 简化了对象之间的连接,只需保持一个指向其后继者的引用,不需要保持其他所有处理者的引用,避免了多重 if …else(因为if else 在场景类角色进行了组装,而事件处理则在具体处理者内)
- 具体处理者责任分担单一,每个具体处理者只需处理本职工作,如果无法处理就传递给下一个具体处理者,如果当前处理者已经是最后一个处理者,那么直接 else 结束责任链即可 (符合类的单一职责原则)~
缺点
- 责任链的长短,从一定程度上影响性能(好比 if(i=1000) 才做逻辑处理,那么正常的话,这个责任链就走了1000次,遇到这样场景的时候性能就非常low了 ~)
- 不是每一个请求都可以被处理,如果所有处理者均无法处理当前请求,那么打到链条末尾会走最终的else操作
- 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用
基础实现
Demo - 思想
好比五星级大酒店后厨一般都有不同菜系(川菜、粤菜) 的厨师,然后我去点个菜系拿手菜之酸菜鱼,之后酒店就要看我这个酸菜鱼让哪个菜系师傅来给我炒菜了(这时候肯定就会挨个问厨师,谁会做这个菜咯 (其中 是否会做酸菜鱼就是我们的if条件)) > < ~
Demo - 效果
if else 方式
void whoFry(String food){
if (food.equals("水煮鱼")){
Log.e("tag","粤菜厨师来炒");
}else if(food.equals("酸菜鱼")){
Log.e("tag","川菜时候来炒");
}else{
Log.e("tag","此菜无人可做");
}
}
责任链方式
抽象处理者
/**
* @author MrLiu
* @date 2020/7/2
* desc 抽象处理者
*/
public abstract class DutyHandler {
public DutyHandler nextHandle;
public DutyHandler getNextHandle() {
return nextHandle;
}
public void setNextHandle(DutyHandler nextHandle) {
this.nextHandle = nextHandle;
}
/**
* 处理请求的方法
*/
abstract void handleRequest(String request);
}
具体处理者 A
import android.util.Log;
/**
* @author MrLiu
* @date 2020/7/2
* desc 具体处理者 - 粤菜厨师
*/
public class ConcreteHandler_A extends DutyHandler {
@Override
void handleRequest(String request) {
if (("脆炸鱼柳").equals(request)) {
Log.e("tag", "具体处理者A - 粤菜厨师:so easy,大兄弟 ~");
} else {
if (getNextHandle() != null) {
getNextHandle().handleRequest(request);
} else {
Log.e("tag", "此菜无人可做 ~");
}
}
}
}
具体处理者 B
import android.util.Log;
/**
* @author MrLiu
* @date 2020/7/2
* desc 具体处理者 - 川菜厨师
*/
public class ConcreteHandler_B extends DutyHandler {
@Override
void handleRequest(String request) {
if (("水煮鱼").equals(request)) {
Log.e("tag", "具体处理者B - 川菜厨师:so easy,大兄弟 ~");
} else {
if (getNextHandle() != null) {
getNextHandle().handleRequest(request);
} else {
Log.e("tag", "此菜无人可做 ~");
}
}
}
}
场景类
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建具体处理人
DutyHandler duty1 = new ConcreteHandler_A();
DutyHandler duty2 = new ConcreteHandler_B();
//组装责任链
duty1.setNextHandle(duty2);
//开始责任链模式
duty1.handleRequest("酸菜鱼");
}
}