《架构整洁之道》读后感之一:组件设计变化的一个例子

最后都变了- 提交于 2020-11-21 10:26:56

在设计、划分软件组件时,需要平衡组件复用、组件发布、组件维护更新等多方面因素,最终得结果是各个方面平衡得结果,可能从某一方面看并不完美。

在Bob大叔的《架构整洁之道》中给出了与构建组件相关的基本原则:

  • REP:复用/发布等同原则
  • CCP:共同闭包原则
  • CRP:共同复用原则

在实际决策中,往往会发现很难同时遵守上面的原则,需要根据具体情况会有取舍;很多的情况是,在设计时只是考虑到其中的某一个方面,或者随着项目的进展,情况发生了变化,需要修改当初的设计。这里举一个DNN(DotNetNuke)模块的开发中,我遇到过的组件设计问题。

 

 

我从2004年开始从事DotNetNuke的模块开发(ZLDNN.COM),开发的模块在DNNStore(从前叫做Snowcovered.com)中进行销售。其中,从2006年开始开发的DNNArticle是一个比较成功的产品,在开发后来的新模块产品时,发现DNNArticle中的很多功能模块是可以供这些新产品使用的,为了减少新产品开发的工作量,我把这些公共功能抽提出来,形成一个公共的类库,在开发新产品时供自己和开发合作伙伴使用。最初,这样做的效果很好,提高了新产品的开发效率,很多新模块使用这个公共类库,依赖这个公共类库。这种依赖带来的耦合性,埋下了问题的隐患。公共类库被打包到产品模块的安装包中,在安装时由DNN的安装向导进行安装,为了方便用户,减少安装步骤,每个产品模块中都包括了公共类库。随着时间的推移,一些新的功能增加到类库中,类库中原有的bug被修改,新的类库随模块的新版本发布。我们考虑到了产品升级可能带来的问题,比如用户购买了DNNArticle和Advanced Business Directory, 这两个模块都使用了公共类库,当DNNArticle升级时,公共类库被更新了,Advanced Business Directory仍然可以正常工作。我们使模块不依赖于公共类库的具体版本,从而确保旧的模块可以与新的类库共同工作而不需要重新编译。但我们没有考虑到的是,使用新类库的模块不能与老的公共类库一起工作,因此问题发生了,开始有用户抱怨购买了两个模块,安装完一个后,另一个模块不能工作了,类似的抱怨越来越多。问题出在公共类库上:一个模块用到了新版本的类库,另一个模块使用的是老的类库,用户在安装时,先安装了新版本类库的模块,在安装另一个模块时,老的类库覆盖了新的类库,导致了这个问题。这种问题出现时,类库已经在很多产品中使用了,并且已经有相当多的版本发布了,为了快速解决问题,采用了比较笨的办法,舍弃复用性,将公共类库的代码转移到各个产品中,这样各个产品不会因为公共类库产生耦合,也就不会在部署中产生问题。

 

是否有更好的办法呢?有个办法是将公共库单独打包,在部署时,单独部署,如果已经有高版本存在,则不进行部署,这个办法最好,但增加了用户部署产品的步骤,用户总是希望更少的部署步骤。对于只购买一个产品的用户来说,更是如此。从产品的竞争力考虑,这个方案被否定了。 那么采用公共库的设计思路是不是完全不正确呢?应该也不是,在开始阶段,公共库的使用提高了新产品的开发速度,产生了新的销售收入,问题的出现毕竟是一年多以后的事情。也可以这样说,组件的划分不是一成不变的,随着环境的变化,考虑的重点会发生变化,组件的设计也会变化。

 

用《架构整洁之道》第13章 组件聚合的小结作为结束: “在决定将哪些类归为同一个组件时,必须要考虑到研发性与复用性之间的矛盾,并根据应用程序的需要来平衡这两个矛盾,这是一件很不容易的事。而且,这种平衡本身也在不断变化。也就是说,当下适用的分割方式可能明年就不再适用了。所以,组件的构成安排应随着项目重心的不同,以及研发性与复用性的不同而不断演化。”

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!