在一般情况下,任何层次的软件设计如果依赖于不需要的东西,都会是有害的。从源代码层次来说,这样的依赖会导致不必要的重新编译和重新部署,对更高层次的软件架构设计来说,问题也是类似的。
任何层次的软件设计如果它依赖了它并不需要的东西,就会带来意料之外的麻烦。
依赖反转原则主要想告诉我们的是,如果想要设计一个灵活的系统,在源代码层次的依赖关系中就应该多引用抽象类型,而非具体实现。
复用/发布等同原则
共同闭包原则
我们应该将那些会同时修改,并且为相同目的而修改的类放到同一个组件中,而将不同时修改,并且不会为相同目的而修改的那些类放到不同的组件中。
共同复用原则
不要强迫一个组件的用户依赖他们不需要的东西。不要依赖不要用到的东西。
无环依赖原则
稳定依赖原则
稳定抽象原则
软件系统的架构质量是由它的构建者所决定的,软件架构这项工作的实质就是规划如何将系统划分成组件,并安排好组件之间的排列关系,以及组件之间互相通信的方式。
开发高层策略时有意地让自己摆脱具体细节的纠缠,我们就可以将与具体实现相关细节推迟或延后,因为越到项目的后期,我们就越拥有更多的信息来做出合理的决策。
设备无关系,高层策略和底层实现细节的分离。
优秀的架构师会小心地将软件高层策略 与其底层策略实现隔开,让高层策略与实现细节脱钩,使其策略部分完全不需要关心底层细节,当然也不会对这些细节的任何形式的依赖。优秀的架构师所设计的策略应该允许系统尽可能地推迟与细节实现相关的决策,越晚决策越好。
按层解耦,按用例解耦,隔离那些变更原因不同的部分,集成变更原因相同的部分。
我们一定要小心避免陷入对任何重复都要立即消除的应激反应模式中。一定要确保这些消除动作只针对那些真正意义上的重复。
边界应该画在那些不相关的事情中间。GUI与业务逻辑无关,所以两者之间应该有一条边界线。数据库与GUI无关,这两者之间应该有一条边界线。数据库又与业务逻辑无关,所以两者之间也应该有一条边界性。
IO是无关紧要的。
确保高层服务的源码中没有包含任何与底层服务相关的信息。
软件架构设计的工作重点之一就是,将这些策略彼此分离,然后将它们按照变更的方式重新分组。其中变更原因,时间和层次相同的策略应该被分到同一个组件中。反之,变更原因,时间和层次不同的策略应该分属于不同的组件。
底层组件应该成为高层组件的插件。
一个良好的架构设计应该围绕用例展开,这样的架构设计可以在脱离框架,工具以及使用环境的情况下完整地描述用例。良好的架构设计应该尽可能地允许用户推迟和延后决定采用什么框架,数据库,WEB服务以及其他与环境相关的工具。框架应该是一个可选项。良好的结构设计应该只关注用例,并能够将它们和其他的周边因素隔离。
可测试的架构设计
如果系统架构的所有设计都是围绕用例展开的,并且在使用框架的问题上保持谨慎的态度,那么我们就应该可以在不依赖任何框架的情况下针对这些用例进行单元测试。另外,我们在运行测试的时候不应该运行web服务器,也不应该需要连接数据库。我们测试的应该只是一个建的业务实体对象,没有任何与框架,数据库相关的依赖关系。总而言之,我们应该通过用例对象来调度业务实现对象,确保所有测试不依赖框架。
六边形架构,DIC架构,整洁架构
都是按照不同关注点对软件进行分割。也就是说,这些架构都会将软件切割成不同的层,至少有一层只是包含该软件的业务逻辑,而用户接口,系统接口则属于其他层。
独立于框架,可被测试,独立于UI,独立于数据库,独立于任何外部机构
整洁架构
外圆代表的是机制,内圆代表的是策略。
源码中的依赖关系必须只指向同心圆的内层,即由底层指向高层。任何属于内圆中的代码都不应该出现在外层圆中。
如果不考虑具体的实现细节,再好的设计也无法长久。必须要将设计映射到对应的代码结构上,考虑如何组织代码树,以及编译时期和运行时期采用哪种解耦的模式。
就像学习骑自行车一样,单纯的靠阅读是无法掌握软件设计方法的。为了让我们从这本书中获取最大化利益,亲自实践是必不可少的。