职责链的应用

贵有恒,何必三更起、五更眠、最无益,只怕一日曝、十日寒。这篇文章主要讲述职责链的应用相关的知识,希望能为你提供帮助。
?目的:使用职责链形式,替换复杂、特殊的if/else语句。
职责链定义:将处理逻辑封装起来,并按照从普通到特殊的层次优先级处理,如果在一个层次被正确处理,则处理结束;否则传递到下一层次。

一、常用示例如果代码中,满足条件:condition2,只有在condition1失败后采取判断执行,condition n,只有在condition n-1失败时才执行(如下所示)。恭喜,这是一个职责链的雏形。

Funcition() { if (condition 1) { statements 1; } else { if (condition 2) { statements 2; } else { ...; } } // no more statements; }

上述if代码段,实际集成了3个变化点(一般的分支语句,其实都有这3个变化点):
  1. 实现条件逻辑的处理代码(封装到函数中)。
  2. 将条件逻辑与处理代码关联。
  3. 以条件逻辑选择分支,执行处理代码。
下面将以职责链形式,来重新实现代码的结构。

二、简单条件逻辑形式的职责链原始代码中,变化点2、3混合在一起;而且代码格式没有显示的模块化。如果逻辑变得复杂,理解和维护都会逐渐变差。
简单改变程序代码,去掉else,减少缩进,得到简单条件逻辑形式的职责链。如下所示:
Funcition() { if (condition 1) { statements 1; return; }if (condition 2) { statements 2; return; }...; }

这样做,不符合标准的“一个输入、一个输出”原则,但在这种情况下,多个输出的做法有以下优点:
  1. 将变化点2以模块化代码段方式独立起来。
  2. 使用代码段先后次序,来控制变化点3。

三、条件函数形式的职责链简单条件逻辑的职责链中,变化点2仍然在调用函数中实现,对调用函数不妥。
将变化点2使用boo函数封装,得到条件函数形式的职责链。如下所示:
Funcition() { if (DoCondition1Ok()) { return; }if (DoCondition2Ok()) { return; } ...; } bool DoCondition1Ok() { if (condition 1) { statements 1; return true; }return false; } bool DoCondition2Ok() { ... }

这样做,有以下优点:
  1. 将变化点2封装到各层的处理函数中。

四、表驱动法的职责链变化点3,仍然在调用函数中实现,对层次较少的处理,这种处理已经足够了。如果处理层次较多,则再使用表驱动法(参考“C++的表驱动法”)。步骤如下:
  1. 将处理函数,按优先级,使用list结构存储起来;
  2. 在调用函数中,使用迭代循环方式,逐个执行处理函数。
  3. 如果处理函数执行正确,则返回;否则进入下一层继续执行,直到循环结束。

五、职责链模式如果变化点1、2的结构比较复杂,则表驱动法中的函数级封装可能就显得力不从心。此时,使用职责链模式提供更大粒度的封装。将变化点1使用类封装,变化点3使用模式的“连接后继者”在创建时自动维护(具体参见《设计模式》)。

参考文献
  1. 《代码大全》(第2版)中文版,第18章 表驱动法。
  2. 《设计模式》中文版,第5章,5.1 职责链。
【职责链的应用】?
职责链的应用

文章图片


    推荐阅读