《架构整洁之道》读后笔记

《架构整洁之道》读后笔记

很遗憾怎么没早点遇到这样的书,如饥似渴多看完了,每章内容不多,却都非常精辟,结合自己的经验,梳理了一些自己的理解。

编程范式

面向结构化编程

赋予了我们组建可被证伪的组件能力,因为通过控制、逻辑、循环语句拼接的代码可被证明正确,也可以通过测试来证明一定情况下不被证伪,这段逻辑就是正确的,继而说明整个程序是正确的。

面向对象编程

核心是可以利用多态,将逻辑控制依赖和物理依赖也就是代码、模块、部署依赖反转,这样就可以独立开发、部署。而且理论上任何形式的依赖都可以随意控制。

函数式编程

限制赋值,可以线程安全

设计原则

SOLID原则

SRP:单一职责

一个类或者模块,只有一个原因可以修改。

OCP:开闭原则

一个类如果不想被其他类的修改所影响,那就让其他类来依赖这个类。越核心、越高层的类,越应该被依赖。这样周边功能扩展的时候,就不会修改到核心的类。

LSP:里氏替换原则

如果依赖的类和其实现不直接依赖,可直接替换,那就是满足LSP设计的。对于抽象良好的接口,任何实现类都可以直接替换接口而对调用方无影响。

ISP:接口隔离原则

不要依赖不需要的东西,否则被修改的时候,需要重新编译、部署,组件出现故障的时候也会受到影响。

DIP:依赖反转原则

软件设计中应该依赖于抽象,因为其比具体实现更稳定,包括对象的创建;尽量不要用继承,不要override具体实现的函数;避免在代码命名与任何具体实现的或者容易变动的事务名字。

组件构建原则

组件设计原则

REP:复用发布等同原则

也就是发布最小粒度和组件复用粒度要等同。组件粒度比发布粒度大,会让开发人员叫苦,因为不同组件的发布节奏可能是不一样的。而组件粒度比发布粒度小,回产生过多的发布。为复用者而发布

CCP:共同闭包原则

类似OCP,一个组件应该只有一个被修改的原因,将由于不同原因而修改的东西分开。违反这个原则,会让修改分布在很多组件里,每次发布都无法做到组件独立发布和部署。

CRP:

不是紧密相关的类,不应该放在一个组件里,防止无用的依赖,变更的时候影响依赖方。

组件原则

组件设计的时候,是在以上原则之间平衡。(其实好像讲的是一件事?)(也有评论表示,这已经是现代软件设计的基本原则了)

组件耦合原则

无依赖环

组件之间的依赖必须不包含环,否则很难进行修改和集成。

稳定依赖

不稳定的组件,需要依赖稳定的组件。当出现违反的时候,需要用依赖反转增加组件来反转依赖。

稳定抽象

组件越稳定,就越应该设计足够抽象让其可扩展。当违反的时候,可能会让稳定的组件难以被修改。
以上稳定和抽象指标,可以评估组件的健康程度,应该尽量的让组件设计在稳定抽象-不稳定具象的主序列线上,并尽量靠近主线。指标化可以分析和监控组件间关系的健康程度,并加以改进。

软件架构

软件架构设计很少能影响系统行为,其主要目的是支撑软件全生命周期,可以让系统便于理解、易于修改、方便维护,并且可以轻松部署,最大化团队生产率,最小化系统运营成本。

软件架构设计,应该避免让高层策略也就是核心业务逻辑,和底层实现细节如数据库、发布形式、框架等耦合,而且要尽量晚的为细节实现做决策。

设计良好的架构,应该用保持可选项的方式,让系统在任何时候都能够方便的做出必要的变更。满足系统架构设计的目标:用例与正常运行、部署、开发、维护。可以按照水平分层或者用例解耦,选择在源代码、二进制、服务层面进行解耦,并能够把解耦模式也作为系统可选项,在上述过程中,让大部分源码不受变更影响,用任何一种方式部署。

划分边界

非常重要,决定了什么地方利用抽象做依赖反转
将与业务逻辑无关的地方,与核心业务逻辑之间划清边界,让外边无关紧要的模块依赖核心模块,让变更频繁和稳定的模块划清边界,让核心模块对周围的变更免疫。构建插件式架构(跨平台和跨端的应用)。(回顾修改引入的问题单,有没有一个模块的修改影响到另一个模块功能的情况)

边界剖析

不同的边界划分策略,单体架构常用源码层次的解耦;更进一步,用部署层次的解耦,不同组件划分高低层次;体量再大时,用本地进程方式在运行时解耦;最后最强的边界是服务解耦,不是在不同的服务器上。整体上都是底层组件依赖高层组件,并且一个项目中往往是多种边界解耦方式并存。

策略与层次

离输入输出越远的模块,层次越高,反之则越低。让底层依赖高层,将依赖方向和数据、控制方向解耦。

业务逻辑

业务逻辑是核心功能,是用来赚钱或者省钱的那部分程序和程序处理的数据。用例不要包含输入输出的细节实现,是特定场景下的业务逻辑,对业务实体关键方法调用的组合。

架构设计的主题

架构设计应该围绕用例展开,应该为系统的用例提供支持,这样可以脱离框架和具体实现去完整的描述用例,让架构一看起来就知道是为什呢业务服务的。将框架作为可选项,可以很容易改变。
《Object Oriented Software Engineering-A Use Case Driven Approach》

整洁架构

业务实体:核心业务逻辑
用例:特定场景下,依赖业务逻辑,结合输入输出,完成用例,可以理解为Service层
展示器:负责业务实体和外层框架的数据结构的转换,包含完整的GUI框架和持久化过程
外部框架:只是内层的粘合代码,包含所有实现细节
关键是控制流和依赖顺序是无关的,利用DIP来调整代码的依赖关系,来限制控制流如何跨越边界。

展示器(presenter)和谦卑对象

将难以测试的部分比如GUI的显示部分,尽量简化成只做简单的数据展示工作,将视图里设置值的逻辑部分,纳入可测试范围。对应到当前项目用的mvvm和databinding,其实vm里做数据转换那部分逻辑,就是presenter,负责把model数据转化成视图要显示的数据,而处于xml里的databinding,就是属于视图的部分,只负责展示vm里的数据,基本符合这个原则实践。
谦卑对象通常处于跨边界的地方,只做两个系统边界上简单的数据结构转换。比如项目里的路由框架、controller前面做数据反序列化的框架等。这种对象不应该对数据做任何处理,可以框架化,可以提高整个系统的可测试性。

不完全边界

在没有必要做物理上部署隔离的时候,依然可以先在源码层面提前设计组件隔离,这样可以在组件需要拆分的时候随时拆出去。但是这样的隔离依赖开发人员的规范性,如果管理不善,有可能会在需要拆分的时候带来困难。有几种策略可以选择:组件还是一起打包、策略模式、Facade模式,如何去选择使用哪种策略,是需要根据业务的实际情况去选择。

层次与边界

这章带我们从一个非常简单的游戏出发,通过分析业务的需求演进,如何对可变/不可变的部分进行分层并划分边界,如何设计抽象接口让依赖反转。而这些事情是需要架构师不断的在业务发展过程中进行思考、改变的事情。

Main组件

最底层的模块,包含很多实现细节,需要把核心模块的底层组件注入到高层模块里并构建起来。这里可以对程序运行时的具体环境进行切换和配置,比如Android应用的服务端环境、配置信息、包名、特性开关等信息。

服务:宏观与微观

这章警醒了我!所谓服务即架构 其实是不存在的,无论是面向微服务,还是移动端的面向插件化、组件化,都只是调用方式上的变化,没有真正对架构上做解耦,实际上遇到跨越式变更的时候,还是需要所有的模块都要一起变更,压根没有解耦一说。真正需要架构解耦的,需要遵循面向对象设计原则SOLID,设计系统中的依赖关系;或者在服务、组件的内部,遵循这个原则,底层实现依赖高层抽象,才能做到真正意义上的解耦。甚至端云之间耦合过紧,也可能不具备架构意义上的解耦。

测试边界

测试也是系统的一部分,系统设计也要考虑可测试性,体现在:测试不能依赖系统的易变部分,如GUI,防止系统变更的时候因为会导致大量的测试失败而困难,参考谦卑对象,对难以测试的部分用边界划分出去,把逻辑放在克测试的内部,把谦卑对象放在边界上;系统要为可测试性设计,方便构造测试需要的数据、状态、环境,并且把这部分隔离到现网运行和部署到系统之外。

嵌入式整洁架构

虽然这章说的是嵌入式架构,实际上不止嵌入式,其实还是要把会变化的和不会变化的分层隔离,让业务依赖抽象,无论是硬件抽象HAL还是操作系统抽象OSAL,都是这个思路。

实现细节

数据库、GUI、WEB、应用程序框架等,都是实现细节,不应该让这些细节侵入到业务的核心部分,只能存在于层级的最外层。

案例分析

通过视频网站的案例,从业务分析开始,编写用例图,来划分组件。划分冲两个纬度考虑:一个是角色,来源于变更原因的不同;一个是层级,来源于变更频率的不同。可以让我们应对需求可以灵活调整。

拾遗

1.如何避免跨层依赖:可以利用gradle的implementation依赖,避免跨层依赖。
2.一个划分模块的思路:按照组件划分,让UI依赖一个粗粒度的组件,包含业务和持久化代码,做成面向服务的组件模式。UI只是一种不同的发布模式。(思考自己的应用,如果是同一个业务跨平台、跨终端,可以考虑把核心的地方复用,UI分开)
3.利用Java的访问控制修饰符,控制组件里实现类的访问限制,也可以利用语言特性,尽量限制不应该访问的,减少开发人员出错。
整体上就是要考虑执行上的有效性,来设计源码的依赖和组织方式,并且也要防范其他地方的依赖,比如数据结构(我理解就是虽然分了组件,但是边界上发生变化,如果需要同时修改数据结构,耦合就出现了)

总结

架构在敏捷的开发模式下,虽然不需要庞大的顶层设计,但是也需要在敏捷过程中提前为下一步编码考虑。

最后的小故事,作者回忆了从40年代到90年代参与过的项目,不乏反面案例,印象深刻,尤其对于硬件隔离、GUI隔离、数据库隔离等原则,经历了实实在在的教训,很有意思。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值