10.5 软件组件设计原则
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.组件的边界与依赖关系,不仅仅是技术问题。
组件的边界与依赖关系划分,不仅需要考虑技术问题,也要考虑业务场景问题。易变与稳定,依赖与被依赖,都需要放在业务场景中
去考察。有的时候,甚至不只是技术和业务问题,还需要考虑人的问题,在一个复杂的组织中,组件的依赖与设计需要考虑人的因素,
如果组件的功能划分设计到部门的职责边界,甚至会和公司内的政治关联起来。
评论