贫血或职责的讨论

先来点题外话,亚历山大兄弟最近的几篇文章不错,不用太在意细节,揪住细节使劲儿打的家伙很无聊的... 至少我从你的文章里也重新学习了不少东西,不是客气话;我这人基础功很不牢靠的。现在直奔主题吧,咱们也来选下美,看看到底谁更漂亮。这篇只是闲聊,写的 比较随意,大家瞎看看哈。

先来形容一下亚历山大兄弟推荐的那种做法,看看贴切不。这种做法希望从界面到数据, 在某个类能够涵盖的范围内上形成一根通天棍(就跟金箍棒一样), 这个棍只跟自己有关,与别的东西无关。如果所有的东西,都是一根根通天棍,那再好不过,哪个棍都可以自己伸缩着玩。于是亚历山大兄弟就一直在强调封装的好 处,同时提出要考虑耦合。比如还是那个Book和BookManager的例子, 亚历山大兄弟提到BookManager和Book耦合,经常一改全改。 

但是这个事实恐怕经不起推敲:BookManager只是把一根棍换成了两根啊... 说这两根棍有耦合,使得低耦合的原则被破坏了,好像不能轻易盖棺定论。比如只有Book的情况如果要改,虽然不至于改两个类,但是不照样该改多少改多少 吗?从整体来看一根粗棍变成两根挨在一起的细棍,那种耦合程度更低呢? 耦合并不是一个一加一等于二的问题, 产生了一个耦合, 耦合总值就变大了吗?(至于AOP等其它做法, 那就好比给这根棍刷漆把它刷成一根粗棍,先放在一边,不然讨论没头儿了)

既然是挨在一起的两根细棍,那么把BookManager(假设BookManager不包含其它逻辑)和Book看做一个整体,从外部看则这种耦合就无 所谓了。但是从这个整体的内部看,BookMananger和Book在接口不变的情况下却可以分别替换。如果只有一个Book.Save, 不就相当于BookManager整个实现在Book内部了么?  如果真做成一个内部私有类,然后由Book暴露个Save方法而绝对不暴露BookManager,想把BookManager换掉或者扩展,除了硬改代 码还有什么手段?

当然往往我们的BookManager还有好多其它逻辑,这时候看起来Book和BookManager的耦合就比较没道理,因为很可能把Book和与它 无关的内容耦合了。这就好比BookManager这个棍太粗,然后粘着一大堆细棍,哪一根棍的变化都有可能影响别的棍,更何况既然都粘一起了,那就如某 些兄弟的做法,变一根超粗大棍算了。 

至于说有BookManager就会造成Book失血,确实没办法苟同。 因为如果Book不是这么简单的东西,比如还有如何翻页,如何索引某一段内容等逻辑呢? 内部已经存在大量的其它逻辑的情况不是不存在。另外在这种情况下,如何保证类象大嘴们书里推荐的那样,一个健康的类只有200行左右代码? 看来大师的话是怎么看都有理,而大嘴们说的话往往是相互冲突了?我倒是觉得,能当大嘴,至少半瓶子得有吧...

一根棍子细过了头儿,可能性有两种: 一个是不该失血而失血; 另一点是本来它本来就只能失血, 因为这个模型根本就没血(写到这我突然发现我很流氓,不过懒得换说法了)。对于后面这种情况,很多人不承认,有的是基于亚历山大同志的封装好的观点,有 的...确实不知道他们怎么想的。回头说说这个Book,亚历山大同志的反对者都在说Book不会自己进书架;同时我看见有的兄弟说这个Book例子不 好,但这个Book例子是广泛而客观存在的,我觉得换个例子绕过去,得出的结论也不可靠。说到死类的问题上其实是一码事,为什么不能接受死类存在呢? 我觉得很多时候,该死的就得死,死者的职责就是挺尸,出于对死者的尊重,难道还非要把他弄活不成么?

在这一点上,我认同反对者的这一说法, 即Book有Save,那是充了别人的血;平时讨论职责,到了这时候职责又无关紧要了?不过由于我的观点是:不应该是对现实世界的抽象,而是对如何更好的 利用计算机解决某一问题的抽象。当然,在这个过程中可能包含对现实的抽象;同样也可能需要让一些人充其它人的血。这样的话,Book.Save好不好,还 是要看是不是有甜头。我觉得亚历山大同志也有类似的想法,他说Book.Save这种方式好,是基于其它角度出发的。

最后说点闲话,大家经常说在真实项目中自己也不会使用理想的做法, 为什么? 一般人归咎于现实。我觉得有时候不完全是现实原因,还是没有对项目进行超出一般做法的深挖掘,所以没看到如果在深一步复杂度会如何,自然就认为更好的做法 是理想,而不是需要。原来没注册时说过,总有那么几种真正良好的做法,足够的漂亮,而正是因为这种漂亮,所以它也能更好的解决实际问题,而不只是一种理 想。

其实往往项目的要求或对变化的需要更进一步,复杂性就大大增加,这时候我们能不能找到这些漂亮的方法就会变得重要,实现理想的机会反而来了。但由于我们的 客户看上去虽然好像非常不客气和无理,可其实他们根本搞不清楚到底自己要啥,加上项目经理啊之类在中间搞一搞,最终他们提出的要求对于他们的业务来说,根 本是驴唇不对马嘴(想想ERP的失败率),反而经常是一些繁琐,但对项目复杂性无关痛痒的怪要求。

在下一篇文章《怪怪设计论闲谈篇:职责与解耦的矛盾》中, 我将介绍一种同时兼顾Book.Save和BookManager的做法,看看能不能把他们各自的优点整合起来。

posted on 2007-09-24 08:14  怪怪  阅读(880)  评论(0编辑  收藏  举报

导航