2018-11-30 张子阳 推荐: 4 难度: 2
又到了每年的双11,于是到京东看看有什么可买的书,就注意到了这本《架构整洁之道》。Bob大叔之前的几本书《代码整洁之道》和《敏捷软件开发》之前也都读过。这本是今年9月才出的新书,就立即买来读了。
全书近300页,分成了34篇文章,每一篇都比较短小,内容还是比较精炼的。通读过后,感觉相较于作者之前的书,没有太多新的内容,依然是以SOLID为基础,先对这些原则进行解释,再进行扩展和应用。
全书分为了6个部分,第1部分是对架构的概述:
架构(Architecture)和设计(Design)是一回事儿,架构既包含高层架构信息也应包含底层设计细节。
软件架构的终极目标是,用最小的人力成本来满足构建和维护系统的需求。
第2部分对三种编程范式进行了描述:结构化编程、面向对象编程、函数式编程。
结构化编程:将模块递归降解拆分为可推导的单元(函数);不使用goto语句(破坏了程序流程)。
面向对象编程:封装、继承、多态、依赖反转。这里作者指出了像C这样的语言,也可以实现封装和继承等特性,只不过更容易出错。
函数式编程。
第3部分讲解了设计原则
SRP(单一职责原则)
任何一个软件模块都应该有且只有一个被修改的原因;任何一个软件模块都应该只对某一类行为者负责。
OCP(开闭原则)
设计良好的计算机软件应该易于扩展,同时抗拒修改。这里主要举的还是依赖反转的例子,高级组件(如业务逻辑)不因为低阶组件(如数据库)的变化而修改。
LSP(李氏替换原则)
类似于 抽象类的机制,抽象类的调用方不需要知道抽象类的实现类(子类)。发现是否破坏该原则,可以查看下调用方是否有if..else..语句用于判断实现类的类型。
ISP(接口隔离原则)
减少不必要的依赖关系,任何层次的软件设计如果依赖了它并不需要的东西,就会带来意料之外的麻烦。
DIP(依赖反转原则)
源码依赖方向是控制流方向的反转。比如说,本来UserDomain(业务层)依赖于UserRepository(数据访问层),即UserDomain需要引用UserRepository,并且调用UserRepository中的方法。但是如果在UserDomain中加入一个IUserRepository的接口,UserDomain转为调用IUserRepository上的方法。那么UserDomain就不再需要依赖UserRepository,而UserRepository则需要依赖UserDomain。
第4部分讲述了组建构建原则
这部分实际是将上面的SOLID原则应用到了组件层面。这里提出了组件的稳定性概念。依赖关系必须要指向更稳定的方向。任何一个预期会经常变更的组件都不应该被一个难于修改的组件所依赖,否则这个多变的组件也会变得非常难以被修改。
第5部分讲解软件架构
软件架构的实质就是规划如何将系统切分成组件,并安排好组件之间的排列关系,以及组件之间相互通信的方式。
开发的早期阶段不需要去选择数据库、Web服务、依赖注入框架,这些都是细节。
设计良好的架构不会依赖于成堆的脚本和配置文件,也不需要手动创建一堆“有严格要求”的目录和文件。
“整洁架构”,实际上是一个同心圆,最核心是业务实体,外围依次是用例,控制器/网关/展示器,最外部是用户界面/数据库/Web/设备。源码的依赖关系由外层指向内层。
第6部分提到了实现细节
数据库只是实现细节,作者将数据库视为一个长期存储数据的、装满字节的大桶。由此,数据库的功能应当是不包含任何逻辑的,仅仅是存储数据。在早些年的一些项目当中,数据库非常重,包含了大量业务相关的存储过程。
Web只是实现细节,Web只是一种I/O设备,应用程序应该与设备无关。
应用程序框架只是实现细节,应当将框架作为架构最外圈的一个实现细节来使用,不要让它们进入内圈。
这部分印象最深刻的就是不要先行设计数据库表结构。想起以前的自己以及很多开发人员,在做一个项目的时候,最先或者最喜欢干的就是设计表结构,然后从数据库开始向上做业务逻辑。
感谢阅读,希望这篇文章能给你带来帮助!