---
title: 《实现模式》导读
category: 读书笔记
---

“所谓专业和非专业的一个关键区别，就是外行人、票友认为需要灵感的很多东西，在专业人士这儿是可以穷举的。”实现模式就是这样一本定式集，它使用穷举的方式，回答了“编程元素能传达什么信息”的问题，使“编写好代码”走出少数人灵感的殿堂，走入寻常专业者可以学习并掌握的东西。它是所有入门者应当熟记、背诵、内化的基本功。

## 目录

* 价值观
* 原则
* 动机
* 定式

要看到，整本《实现模式》、乃至于敏捷社区的《重构》《测试驱动开发》，既是软件工匠手艺的同时，也都基于这样一个假设：**软件的维护成本比开发成本大得多**。这意味着什么呢？意味着生产出结构糟糕、没有测试的代码，在其诞生的下一秒就会产生巨额的成本，意味着这是专业者不专业的行为。维护的成本主要是什么呢？

```
cost(total) = cost(develop) + cost(maintain)

cost(maintain) = cost(understand) + cost(change) + cost(test) + cost(deploy)
```

是理解+更改+测试+部署的成本。部署成本不在此书谈论之列，自动化测试也不在此书谈论之列，于是主要的便是其余两种成本：理解代码、更改代码的成本。于是，**所谓“写好代码”，便主要是指写出易理解、易修改的代码**，这不仅是种专业行为，同时是种经济行为。

## 价值观

上面基本上阐述了软件工作者的价值观，于Kent Beck表述起来就两点：**沟通**、**简单**。还有一点灵活被我略去。沟通本质上便是使代码易于被理解、简单既意味着易理解，也意味着易修改。

保持简单，意味着：仅保留最小的有价值的需求、移除所有多余无关的设计元素和编程元素；也意味着更加直观的修改。

保持沟通，意味着：使用编程元素（类、函数、变量、语法）来传达所有代码和设计的意图。

这是专业人士写代码的两个基本的目标，也是敏捷社区、作为软件专业人士应该持有的价值观。如果你不认可这个价值观，那么你可以放下这本书、放下这篇笔记了。

## 原则

基于这两个大的愿景，Kent又提出了若干稍为具体一些的原则性指导，分为六条，基于上都是服务于“易理解”“易修改”这两个目标。

### 局部化影响

* 使相关的变化只在一处发生
* 实在须发生在多处时，使其发生地点变近

这是事关“易修改”性的建议。

### 最小化重复

这同样事关“易理解”和“易修改”：若有重复的代码，读者便会生起疑问：“为何重复？”“能否消除重复？”这便影响了理解；进而修改时需要修改多处，维护者也不定能得知“还需要修改别处”“应修改何处”的信息，“易修改”的目标便打了折扣。

最小化重复，实质上也支撑了“局部化修改”。极端的建议是：消除任何形式的重复。

### 面向对象地组织数据和逻辑

实质上也是在支撑“局部化影响”原则：将与数据相关的行为拖放到与行为一起，既易于理解，也易于修改。现代写JS的项目容易忘记这条来自面向对象世界的箴言。使用对象太少。

### 对称性 

这是与“易理解”更为相关的建议。具体是啥意思呢？对称性指的是代码具备：形式上的对称性、时间上的对称性等、空间上的对称性等，这表达了代码具有“类似”的行为，从而使你能从对称的一方，快速推知对称的另一方。比如：

* 形式（功能）对称：`add()` / `remove()` 方法成对出现
* 时间（生命周期）对称：`componentWillMount()` / `componentWillUnmount()`
* 空间（结构）对称：一组方法接受同样的参数，等

### 声明式

这条服务于“易理解”的价值观，事实上也是更为广阔的编程建议：代码要表达其意图，隐藏其细节。

比如React、vue、angular等前端框架，便支持了生命式地编写HTML及其逻辑，声明式地描述用户界面。

### 变化率

把相对容易变化的代码放到一起，相对稳定的代码另放到一起，以支持快速对易于变化的部分进行修改。这与“局部化影响”建议相辅相成，更多服务于“易修改”的代码愿景。然而，分辨“是否容易变化”并不容易，也只有靠重构不断调整修正。

## 动机

为啥要写好代码呢？实现功能就完了，为啥还要让代码易理解、易修改、给它添加100%的自动化测试呢？

* 写好代码确实不保证一定“赚大钱”或“成功”，但易理解易修改的代码，主观上增加了项目成功的概率
* 不写好，短期讲，出了bug你会被骂
* 不写好，长期讲，要对历史发展进程有信心，行业一定会淘汰掉手艺不精者
