《架构整洁之道》读书笔记(四)——组件原则

2019-02-16

这里对组件的含义是:软件部署的单位,是能做为系统的一部分部署的最小实体。组件可以是Java中的JAR、Ruby Gem,或.Net中的DLL文件。组件或者被连接成单个可执行文件,或者聚合为单个构建结果(archive),比如Java中的.war文件。组件也可能被以运行时动态加载的插件形式独立部署。总之,良好设计的组件总是具备独立部署的能力,这也就意味着组件可以(被单个开发团队)独立地开发。

三个将类(广义地指“以一定的耦合性组合在一起的函数与数据”。)组合成组件的原则是:

  • REP : 重用/发布等价原则
  • CCP : 共同封闭原则
  • CRP : 共同重用原则,即只要依赖了其中一个类,那么也会间接依赖到其它类。

综合这三个原则,被组合在同一个组件中的类应该有这样的特征:

  • 有相同的修改动因(SRP原则在组件层次的应用。)
  • 往往会同时变化(被修改)
  • 会被同时重用
  • (同一组件内的类之间)有比较多的依赖关系

不满足这些条件的类说明它们之间没有强烈的互相绑定(bound)关系,不应该包含在同一个组件内。而如果同一个组件中的类满足这些条件,那么当面临一个需求变化的时候,需要修改的组件数量可以压缩到最小的限度(最好只局限在一个组件内部)。

这里更多说一下REP,因为我觉得书中对REP解释得还不够清楚,我又查了一下作者之前写的关于REP的文章,理解REP包含了三层意思:

  1. 组件重用的粒度也是发布的力度,这个粒度就是“package”。
  2. 赋予”package”版本号,并使用包管理系统来跟踪和管理。比如Java中的maven,node的npm,ruby gems等。
  3. 遵循一个流程来通知组件新版本的发布、以及新版本中包含的修改内容。

这就是“被组合在一个组件中的类和模块应该共同发布”的具体含义。显然“Ctrl-C Ctrl-V”不是真正的重用。

三个原则中REP和CCP是“包容性”原则,也就是指导我们哪些类应该包含在组件中。CRP是“排斥性”原则,即指导我们哪些类不应该被包含在一个组件中。

  • REP将类组合在一起的主要考虑是便于重用。
  • CCP将类组合在一起的主要考虑是便于维护。
  • CRP将类分开(到不同的组件),目的是避免频繁的、不必要的发布。

三个原则互相作用构成一个有张力的三角形。

(原图出处)

  • 过于关注REP和CRP会导致需求变更影响的组件过多,因为同一个修改涉及的组件被分散到不同的组件中去了。
  • 过于关注REP和CCP会导致频繁的、非必需的组件版本发布。因为一个组件中可能包含实现不同功能的类,这样当其中一个功能的需求发生变更时,一方面固然只需要修改这一个组件,但是由于整个组件的版本更新、重新发布,依赖到组件中实现其它功能的类的程序可能也需要更新自己依赖的组件。
  • 过于关注CCP和CRP会导致组件难以被重用。

三个原则之间的平衡基本就是开发的方便度(develop-ability)和重用性之间的平衡。往往在项目刚开始的时候,我们会更关注”develop-ability”,更多采用CCP原则,也就是采用比较粗粒度的组件划分、形成比较大的组件。随着项目进行、需求和设计的成熟度的不断提高,甚至有其它项目从原项目中衍生出来,这时我们会更加关注组件重用性。这是作者一再重复的建议,即从粗粒度的组件设计开始,以后再视需要逐渐细化。



blog comments powered by Disqus