今天来总结一下自己对责任链模式的感悟。
责任链模式
1.WHAT -- 什么是责任链模式
责任链模式是一种对象的行为模式,是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。
2. WHEN -- 什么情况下使用策略模式
现在我的项目里有个扫码功能需要实现。
扫码功能需求
- 扫码需要实现的功能有:A-扫码登录、B-扫码交接(业务功能)、C-扫码跳转页面;
- 上述扫码功能统一是由首页右上角扫码入口进入,根据所扫二维码中携带的信息,依次进行扫码登录、扫码跳转界面和扫码交接(业务功能)。
即该功能只有一个入口,且后续的各种操作都为串行操作。
初版设计方案
- 对3个扫码功能进行封装,得到3个扫码功能方法:handleA()、handleB()、handleC()
- 创建一个工具类,编写一个handleScanResult(String result)方法,在该方法中通过对result进行判断,然后在第一步的三个方法中选择进行执行。 代码实现大概就是下面这个样子:
...
if (scanResult.contains('aaa')){
handleA(scanResult);
handleB(scanResult); // 有些操作可能不需要跳转
if (scanResult.contains('ccc')) {
handleC(scanResult);
}
}
...
这样写有什么问题呢? 分析一下:
- 如果存在连续处理业务的时候就会导致嵌套很深,会增加维护成本;
- 如果后续
操作顺序或者操作流程改变,则需要对该段代码进行大规模的改动,也会增加维护成本。
所以在功能操作串行的背景下,为了解决上述问题:if-else嵌套、违反开闭原则,则可以使用责任链模式。
3. HOW -- 怎么使用责任链模式
- 创建
操作节点base类(虚拟类):BaseHandle;
该类中包含:
属性:BaseHandle nextHandle(串行操作中下一个操作节点);
方法:1:设置下一个节点的方法:BaseHandle next(BaseHandle next)、2:节点操作入口方法 bool handle(result)、3:该节点的具体处理逻辑方法(虚拟方法)bool handleLogic(String result)、4:是否需要该节点处理方法(虚拟方法)bool isNeedHandle(result);
/// 具体功能虚拟类
abstract class BaseHandle {
// 下个处理节点
BaseHandle? nextHandle;
// 节点处理入口
bool handle(result) {
if (!isNeedHandle(result)) {
if (null != nextHandle) {
return nextHandle!.handle(result);
}
return false;
}
return handleLogic(result);
}
// 具体处理逻辑
bool handleLogic(result);
// 是否需要当前节点来进行处理
bool isNeedHandle(result);
// 设置下个处理节点
BaseHandle next(BaseHandle handle) {
nextHandle = handle;
return handle;
}
}
- 创建具体的节点操作类,该类
继承BaseHandle类,实现handleLogic方法、isNeedHandle方法
- 在具体使用时,创建多个具体节点操作类对象,如handleA、handleB、handleC...,并根据相应的
业务执行串行顺序,来进行设置对应的下一个节点。如:串行执行顺序为A->C->B,则需要设置为handleA.next(handleC); handleC.next(handleB);
- 调用入口函数。如
handleA.handle('xxxxxxxxx')。
4. WHY -- 为什么责任链模式能够解决串行操作背景下的嵌套问题和违反开闭原则
- 首先对每个操作进行了封装,使得各个操作直接进行解耦;
- 其次将每个操作的判断都放在了操作的封装类中,所以会把
if-else都取消,即不存在if-else嵌套的问题。- 后续对操作流程和操作顺序修改时,只需要增加或修改对应的
handleX.next(handleY);代码段的顺序即可,无需再对大段的if-else嵌套进行解读和处理。