延迟决策 (Decide as late as possible) 是精益软件开发中的一条规则, 它鼓励把决策的下达延迟到最后可以容忍的时间点:
对流程而言
等到真正需要做改变的时候再做决策, 提前的变更只会增加无形的成本
对人而言
等到做决策所需要的信息较充分后, 再来做判断会比较正确
以上的它的定义, 今天我们要谈的是延迟决策在软件设计中的实际应用, 让我们举个例子, 背景如下:
我们现在有一个提供交易所债券的订单服务, 交易所债券订单很显然是一个领域实体 --BondOrderEntity, 而创建这个领域实体有一个相应的数据服务 --BondOrderDataService, 用于组装领域实体的数据.
现在我们需要支持银行间债券业务, 而银行间债券与交易所债券之间有大量的数据是重复的, 有一部分是各自独有的, 那么问题来了, 我们是倾向于创建一个新的银行间订单实体以及相应的数据组装服务呢? 还是在原有的 BondOrderEntity 中将两部分的数据都加上呢?
一个很明显的参考因素是: 到底有多少数据是不同的?
假如有超过 10 个数据点都是不同的, 那很可能我们倾向于创建一个新的实体, 如果只有 2 个数据点不同呢? 实在是令人纠结.
如果不分开, 一旦业务发生变化, 那么就很容易产生破窗效应, 一不小心这个实体就膨胀了, 到时数据实体 BondOrderEntity 以及数据服务 BondOrderDataService 中会揉杂一堆数据, 局时就很难区分出来哪个业务使用了哪些数据;
而如果现在就分开, 那么又会觉得有点小题大做, 如果业务未发生大的变化就有点浪费.
这里我们就可以考虑使用延迟决策了, 需要注意的是并非是不决策, 而是采用数据结构的方式进行软隔离, 也就是说: 我们将交易所债券与银行间债券订单中公用的数据仍然放在 BondOrderDataService 的数据加载方法中, 而将交易所债券独有的数据点, 增加一个方法返回, 返回一个数据结构, 比如 ExchangeBondOrderObject, 另外将 ** 银行间债券订单中独有的数据点, 放在另外一个方法中进行加载, 返回另外一个数据结构, 比如 InterBankBondOrderObject, 这样, 我们就通过数据结构的方式进行了软隔离, 进而达到延迟决策的目的.
如果未来业务不发生变化, 或者变化的都是公共的数据点, 那么代码基本上也不需要调整;
如果未来业务发生大变化, 那么我们通过不同的结构很容易将分别归属于两个业务实体的数据一刀就切出来, 变成两个实体与相应的数据服务, 公共部分在实体层面, 可以使用继承, 在服务层面, 可以使用组合.
我们通过数据结构, 用软隔离的方式, 把决策的下达延迟到最后可以容忍的时间点, 等到真正需要做改变的时候再做决策, 进而达成了节约的目的.
来源: http://www.jianshu.com/p/0a2c92aa4101