作软件工程师,难!
在现实中,你要努力地求偶;而在程序的世界里却要千方百计地解耦。现实中的偶,成就美满之家,而程序中的耦却带来烦恼。
在序言中,村长通过组建交易委员会的方式,化解了买卖双方的困境。为此,本台记者曾经采访过村长,问他为什么会采用这样的办法,村长的回答意味深长:“以郑屠为例,他是一个专业杀猪和剔肉的,让他同时再去管理各种购买信息外加送货就会让他分心,结果是两样都干不好。增加交易委员会可以从他手上接管订货和送货两个环节,使得他不必分心而是专心地干自己擅长的分内之事。这就叫single-minded”。
我发现村长真的很有智慧,因为他无意间教给了我一种化解软件模块间耦合的重要思想。我把这种思想转化成具体的方法,实施在自己的设计中,起到了奇效。请允许我啰嗦两句,介绍一下这思想的功效。
在刚刚结束的一个软件设计中,我面临了这样一个局面:
有三个存在相互关联的模块,姑且称为A、B和C。他们需要保持同步更新,即其中任何一个模块的状态变化,必须要通知另外两者,以使其跟进,保持一致。关系如下图所示:
对于这样的情况,曾经无数次地面对过,因此我不假思索地采用了最容易想到的方案。在模块A的代码中,完成关键操作后,依次调用模块B和C的对应方法进行相应的同步更新。在B和C的代码中也做了类似的事情。以A为例,代码这么写:
DoMyJob()
B.Tell("地瓜熟了")
C.Tell("地瓜熟了")
我猜有80%的开发者会走这条路,我也曾经是这80%中的一员。但是,在受到村长的启发后,我感受到了烦躁和压力。比如说:
第一、ABC三个类都要相互手持对方的实例。
第二、如果需要关联的模块有增减,需要修改很多处代码,且容易改漏掉。
第三、ABC三个模块不是真正的single-minded,除了自己的业务,他们还需要知道有谁关注他的变化,而且要亲自挨个地去通知人家,多了少了、早了晚了都不可以。好烦呢。如果模块规模不是3而是5,8,甚至更多,这代码还是人写的不是?
基于村长发明的交易委员会思想,我创建了一个专门负责管理关联的模块X,你也可以把他叫做”联络委员会模块”。有了模块X以后,全局模块关系就发生了显著变化,如下图所示: