10.5 软件组件设计原则

用户头像
张荣召
关注
发布于: 2020 年 11 月 28 日

1.软件的复杂度和它的规模成指数关系

一个复杂度为100的软件系统,如果能拆分成两个互不相关,同等规模的子系统,那么每个子系统的复杂度应该是25,而不是50.

软件开发行业很久之前就形成了一个共识,应该将复杂的软件系统进行拆分,

拆成多个更低复杂度的子系统,子系统还可以继续拆分成更小粒度的组件。

也就是说,软件需要规模化和组件化设计。

2.组件内聚原则

关注点:高内聚,低耦合。

组件内聚原则:主要讨论那些类应该聚合在同一个组件中,以便组件技能提供相对完整的功能,又不至于太过庞大。



复用发布等同原则。

共同封闭原则。

共同复用原则。

2.1 复用发布等同原则

复用发布等同原则:软件复用的最小粒度应该等同于其发布的最小粒度。也就是说,如果你希望别人以怎样的粒度复用你的软件,

你就应该以怎样的粒度发布你的软件。这其实就是组件的定义,组件是软件复用和发布的最小粒度软件单元。

这个粒度既是复用的粒度,也是发布的粒度。

比如:Spring 框架,包含的组件。



版本号约定建议:

  • 版本号格式:主版本号.此版本号.修订号。比如:1.3.12;   主版本号1,次版本号3,修订号12

  • 主版本号升级:表示组件发生了步向前兼容的重大修订。

  • 次版本号升级:表示组件进行了重要的功能修订或者bug修复,但是组件是向后兼容的。

  • 修订号升级:表示组件进行了不重要的功能修订或者bug修复。



2.2 共同封闭原则

共同封闭原则:我们应该将那些会同时修改,并且为了相同目的而修改的类放到同一个组件中。

而将不会同时修改,并且不会为了相同目的而修改的类放到不同的组件中。



组件的目的虽然是为了复用,然而开发中常常引发问题的,恰恰在于组件本身的可维护性。

如果组件在自己的生命周期中必须经历各种变更,那么最好不要涉及其他组件。相关的变更都在同一个组件中。

这样,当变更发生的时候,只需要重新发布这个组件就可以了,而不是一大堆组件都收到牵连。



2.3 共同复用原则

共同复用原则:不要强迫一个组件的用户依赖他们不需要的东西。



这个原则一方面是说,我们应该将互相依赖,共同复用的类放在一个组件中。

比如说:一个数据结构容器组件,提供数组,Hash表等各种数据结构容器,

那么对数据结构遍历的类,排序的类也应该放在这个组件中,以使这个组件中的类共同对外提供服务。



另一个方面,这个原则也说明,如果不是被共同依赖的类,就不应该放在同一个组件中。

如果不被依赖的类发生变更,就会引起组件变更,进而引起使用组件的程序发生变更。这样就会导致组件的使用者产生不必要的困扰。

甚至讨厌使用这样的组件,也造成了软件复用的困难。



3.组件耦合原则

组件内聚原则:讨论组件应该包含哪些功能和类。

组件耦合原则:讨论组件之间的耦合关系如何设计。



无循环依赖原则。

稳定依赖原则。

稳定抽象原则。

3.1无循环依赖原则

无循环依赖原则:组件依赖关系中不应该出现环。如果组件A依赖组件B,组件B依赖组件C,组件C又依赖组件A,就形成了循环依赖。



很多时候,循环依赖是在组件的变更过程中逐渐形成的。组件A版本1.0依赖组件B版本1.0,后来组件B升级到1.1,

升级的某个功能依赖组件A的1.0版本,于是形成了循环依赖。如果组件设计的边界不清晰,组件开发设计缺乏评审,

开发者只关注自己的组件,这个项目组件依赖管理没有统一的规则,很有可能出现循环依赖。

3.2稳定依赖原则

稳定依赖原则:组件依赖关系必须指向更稳定的方向。较少并更的组件是稳定的,也就是说,经常变更的软件是不稳定的。

根据稳定依赖原则,不稳定的组件应该依赖稳定的组件,而不是反过来。



反过来说,如果一个组件被更多组件依赖,那么他需要相对是稳定的,因为想要变更一个被很多组件依赖的组件,

本身就是一件困难的事情。相对应的,如果一个组件依赖了很多的组件,那么它相对也是不稳定的,因为它依赖的任何组件变更,

都可能导致自己的变更。



稳定依赖原则通俗的说就是,组件不应该依赖一个比自己还不稳定的组件。

3.3稳定抽象原则

稳定抽象原则:一个组件的抽象化程度应该与其稳定性程度一致。也就是说,一个稳定的组件是抽象的,而不稳定的组件是具体的。



这个原则对具体开发的知道意义就是:如果及设计的组件是具体的,不稳定的,那么可以为这个组件对外提供服务的类设计一组接口,

并把这组接口封装在一个专门的组件中,那么这个组件相对就比较抽象,稳定。



Java中的JDBC就是这样一个例子,我们开发应用程序的时候,只需要使用JDBC的接口编程就可以啦。

而发布应用的时候,我们指定具体的实现组件,可以是MySQL实现的JDBC组件,也可以是Oracle实现的JDBC组件。

4.组件的边界与依赖关系,不仅仅是技术问题。

组件的边界与依赖关系划分,不仅需要考虑技术问题,也要考虑业务场景问题。易变与稳定,依赖与被依赖,都需要放在业务场景中

去考察。有的时候,甚至不只是技术和业务问题,还需要考虑人的问题,在一个复杂的组织中,组件的依赖与设计需要考虑人的因素,

如果组件的功能划分设计到部门的职责边界,甚至会和公司内的政治关联起来。



用户头像

张荣召

关注

还未添加个人签名 2018.05.02 加入

还未添加个人简介

评论

发布
暂无评论
10.5软件组件设计原则