标题可能不好理解,先举一个例子。
在一个会议室预订系统里,有这样一条业务规则:
当收到一个订单时,
if
当天是星期三
then
立即借出
else
交给管理员手动审批
我们把这个规则直接实现在业务方法里,即
class 预订服务{
void 处理订单(){
if(当天是星期三)
借出();
else
交给管理员手动审批;
}
void 借出(){
//to do
}
}
假设系统运行一段时间后,这个业务规则突然被取消了,那就得让开发人员修改这部分代码
又假设业务规则不变,按照这个规则,一个订单被批准。但是由于紧急情况,管理员不得不否决了该订单。可是申请者不知趣,又重新提交该订单、结果订单又被批准,管理员又得强行否决……
所以我们换一个办法。建立一个机器人类,名叫“机器人管理员”。它定时地扫描订单队列,一旦发现有了新订单就立即按照上面所说的业务规则进行处理。
如
class 机器人管理员 extends 管理员 implements Runnable{
void run(){
if(发现新订单){
if(当天是星期三)
借出();
else
交给管理员手动审批;
}
}
}
这样的话,业务规则代码就可以从 预订服务.java中删去了。
当这个业务规则突然被去掉时,我们不需要修改代码,而只需让权限较大的人类管理员在前台界面上,取消该机器人的管理权限
又或者业务规则没被取掉,人类管理员要强行否决一个被机器人批准的订单,同样,他只要先取消该机器人的管理权限,然后强行否决该订单。
总结:我们所做的事就是把被动的规则(它总是“被”使用)从业务方法中剥离出来,建模成机器人(它总是去使用别的东西)。这样做的好处是:
1. 在某些情况下,“操作”(预订) 并不是被操作者(会议室)的职责,而是操作者(管理员)的职责。不能因为这个“操作”是自动的,就让被操作者决定自己是否把自己给卖了。这时候,将这个职责剥离,符合Information Expert模式
2.“自动”操作 与 “手动”操作并存时,就可能会遇到 合作 与 冲突。把自动操作者与手动操作者统一为“操作者”, 就是要将操作者之间的协调与冲突放到业务流程之外。业务流程向所有的操作者只暴露单个接口,至于谁操作了它,谁的操作会不会导致另一个谁不高兴,它没必要知道。不同的操作者也以统一的操作者身分来操作,对被操作者来说,自动与手动的区别是透明的。因此,前面的代码里我们可以将业务规则代码从业务对象中去掉,并让“机器人管理员” 继承了 “管理员”类(显然,管理员的另一个子类是“人类管理员”)。
总之,忘掉“自动操作” 这个想法, 取而代之的是,我们先按常理实现强内聚的、“干净”的业务流程,然后再实现一个“精力充沛超人”,这个超人除了不需要休息,与正常的管理员没什么区别。