Alex' Blog

记录生活和工作

0%

架构整洁之道读书笔记

第一章 什么是架构

架构的目标

以最小的成本构建和维护一个软件系统,满足业务需求(包括当前需求和未来需求)。

常见问题

  1. 忽视好的设计的作用,导致后续维护成本持续增长。
  2. 容忍糟糕的代码,为了临时上线。

Notes

慢但是稳,是成功的秘诀。要跑的快,先要跑得稳。

第二章 两个价值维度

软件的价值

  1. 行为价值(满足业务需求的行为)
  2. 架构价值(软件灵活性,适应后续的需求变更和增加)

研发人员的职责

业务肯定认为行为价值更重要,但是软件开发人员应该重视架构价值,因为一个不可变更或者不可维护的软件系统的价值会最终变成0,而一个维护行好的软件系统会持续产生价值。

业务部门并不对系统的架构价值负责,所以研发人员需要自己平衡好架构价值,并为此负责,与其他部门协调。

第三章 编程范式

结构化编程

结构化编程对程序控制权的直接转移进行了限制和规范。

限制goto

面向对象编程

对程序控制权的间接转移进行了限制和规范

限制函数指针的使用(通过多态)

函数式编程

对程序的赋值进行了限制和规范

不可变性

Note

三个编程范式都是限制程序员行为。

第四章 结构化编程

通过结构化编程,将软件拆分为一个个可推导的单元,通过测试证明这些程序是无法证伪的,则认为程序正确。

按功能性降解拆分是软件设计的最佳实践之一。

第五章 面向对象编程

三大特性

  1. 封装
  2. 继承
  3. 多态

三个特性并不是面向对象编程的创新,之前就通过其他方式实现,但是需要人为遵守规定。面向对象编程消除了人工遵守的必要,通过语言层面实现多态,更简单和安全。

多态的作用

  1. 与具体实现无关
  2. 依赖反转(引入接口)

通过控制组件的依赖,让高层次策略组件和底层实现组件可以相分离,实现独立部署。

第六章 函数式编程

通过变量的不可变性,充分利用多线程的好处,同时避免了变量更改导致的竞争问题。

如果计算和存储无限制的话,不可变性在程序设计中说可行的,例如git版本管理。

在实际情况中,一般说将可变性隔离起来,将不可变量和可变量隔离到不同的组件当中,用合适的机制(锁,事务)保护可变量。

第七章 单一职责原则

定义

一个软件模块,只对某一类行为负责,只对一类客户负责。

Note

单一职责原则主要用于界定函数和类之间的关系,同时,在更高的层面上,比如组件层面,有一个类似的原则,共同闭包原则,在软件架构层面,用于界定架构的边界。

第八章 开闭原则

定义

易于扩展,抗拒修改

Note

高阶组件不因为低阶组件更改而影响

业务逻辑是核心抽象

第九章 里氏替换

定义

所有引用基类的地方必须能透明地使用其子类的对象。

子类可以扩展父类的功能,但不能改变父类原有的功能。

Note

违反LSP原则,系统会不得不增加很多复杂的应对机制。比如各种if else语句

第十章 接口隔离原则

定义

不应该强迫客户依赖于它们不用的方法。

任何让用户依赖他们不需要的东西都是有害的。

Note

不必要的功能代码,导致不必要的重新部署和意外的错误。

第十一章 依赖反转原则

定义

使得高层次的模块不依赖于低层次的模块的实现细节,依赖关系被颠倒(反转),从而使得低层次模块依赖于高层次模块的需求抽象。

规定

  1. 高层次的模块不应该依赖于低层次的模块,两者都应该依赖于抽象接口。
  2. 抽象接口不应该依赖于具体实现。而具体实现则应该依赖于抽象接口。

Note

接口比实现更稳定

不可避免地依赖具体实现,比如操作系统,但是这部分很少改动。

要重点关注经常变动的部分

使得代码依赖是单向的

第十二章 组件

定义

组件是最小部署单元