架构整洁之道读后感
前言部分
是的,在《架构整洁之道》一书中,Bob大叔在前言部分就一语道破天机 — 软件设计发展了这么多年,使用的技术和工具更新换代了无数次,但是软件架构的规则是相同的,而本书正是为了揭示这些永恒的,不变的软件架构规则。关于这一点,笔者在最近几年的阅读和实践中也有类似的感受 — 关于微服务和分布式的思考。
概述部分
本部分共包含两个章节,其中给笔者留下印象比较深刻的是第二章节中关于“软件”的解释 — 软件发明的目的就是让我们可以以一种灵活的方式来改变机器的工作行为,对于机器上那些很难改变的工作行为,我们通常称之为“硬件”。
关于以上这段,结合作者之后的论述,笔者认为,并不是说你所编写的程序就是软件,如果你的程序对依赖毫无控制,任由依赖的侵入,在面对需求时候难以改变,那这样的程序其实并不能称之为“软件”。软件二字重点提现在前面一个“软”字上,其必须有足够的"软",从而确保在面对需求变更或外部条件发生变化时候能够灵活应对。
编程范式
作者在本部分介绍了三种编程范式,基本在这个行业里浸淫过一两年的人,对这三种范式多少都有耳闻。但作者对对这三者的解读以及总结却是诸多在这行业里多年的人都难以望其项背的。作者在本部分的第一章中总结到 — 这三种编程范式都从某一方面限制和规范了程序员的能力,没有一个范式是增加新能力的。
- 结构范式限制了goto语句的使用
- 面向对象限制了函数指针的使用
- 函数式则是限制了赋值语句的使用
以上结论与直觉相反,但静下心来仔细思考,缺又发现确实如此,也许这就是思考的乐趣 — 获得与直觉相反的正确性知识。
另外从1968年至今,人们没有再提出任何新的编程范式,搞不好以后也没有了。
SOLID设计原则
关于大名鼎鼎的SOLID设计原则的名词解释就不用多说了。
作者在本部分分别针对SOLID这五个原则进行了讲解,告诉读者这五个原则不仅仅适用于类和模块的设计,在软件架构层面,它们甚至有着更加重大的意义。
组件构建原则
相较于前面章节指导"将砖块砌成房间",本部分则更上一个层次——传授读者在“将房间组合成房子”过程中需要注意和遵循的原则,这些原则也就是组件构建原则。
为了保证组件的独立部署特性,我们遵循如下基本原则:
- REP:复用/发布等同原则。
- CCP:共同闭包原则。
- CRP:共同复用原则。
而关于组件之间的关系,为了避免组件之间的过度耦合,我们需要遵守如下基本原则:
- ADP:无依赖环原则(P99)。即组件依赖关系图中不应该出现环。
- SDP:稳定依赖原则(P106)。即依赖关系必须要指向更稳定的方向。
- SAP:稳定抽象原则(P112)。即一个组件的抽象化程度应该与其稳定性保持一致。
关于以上六个原则,说来惭愧,虽然多年来未敢放下手中的书籍,但依然只在非常偶然的机会阅读阿里大神梁飞的 以HTTL为例讲讲模块分包&领域模型&扩展框架 时首次接触到类似的概念,Bob大叔这里算是第二次接触。每每念及此,不由得让人心生感慨。
软件架构
在所有六个部分中,本部分是拥有最多的章节的。而在本部分中,作者列举了一个好的软件架构应该支持的目标,以及为此需要注意的事项。鉴于方面较多,而笔者目前的水平也仅限于理解,尚未形成自己的反思和总结,就不在这里大放厥词了。
本部分给笔者影响最深刻的是关于Main组件和测试边界。
- 关于前者,Main组件是整个系统中细节最多的,而且该组件应该是整个系统中的一个底层组件,处于整洁架构的最外圈,主要负责加载所有的必要信息,然后将控制权交回给系统的高层组件。
- 关于后者,只能说笔者最近的经历让笔者对于测试重要性的理解更加深了一步。测试先行,在测试认可了当前改动之后再进行下一步的研发和修复工作。一窝蜂战术那只能将命运交给老天爷。
实现细节
本部分作者用前三章告诉我们:
- 数据库只是实现细节。我们在架构设计时候应该隔离它们。
- Web也只是实现细节。它也只是1960年来数次振荡中的一次,在做架构设计的时候其不应该作为作决定的约束条件。
- 应用程序框架只是实现细节。作者在开篇尖锐地指出框架作者和使用者之间不对等的关系,我们在选择框架时一定要慎重,时刻保持警惕,让框架保持在实现细节之列,避免让其进入架构核心。
关于本部分的拾遗一张,真的给予笔者很大的惊喜,章节作者开篇即道出设计的困难之处往往就在于细节之中,要将设计映射到对应的代码结构上。由此引出了四种安排具体安排代码设计和代码结构的方法:
- 按层封装(水平切分)。经典到看着想吐的Controller,Service,Repository三层架构这一在项目初期比较合适的组织方式。
- 按功能封装(锤子切分)。正如作者所说,这种组织方式好处是代码容易找到,但得益于现代IDE的日益强大,这点好处似乎变得越来越不明显,但让人惭愧的是笔者所在公司的系统更新方式让这种封装方式越来越流行,唉。
- 端口和适配器。这种组织方式下,只有外部能依赖内部代码,反之则不能。
- 按组织封装。 这种组织方式,充分利用了编译器的特性,将一个粗粒度组件相关的所有类放在一个Java包中,只开放必要的public类。这对于笔者有着严重代码洁癖的人来说真是深以为然(基础之访问修饰符)。