主页

索引

模块索引

搜索页面

10x 程序员工作法

目录

《人月神话》中提到两个非常重要的概念:

1. 本质复杂度(Essential Complexity)
    解决一个问题时,无论怎么做都必须要做的事
2. 偶然复杂度(Accident Complexity)
    因为选用的做事方法不当,而导致要多做的事

1975 年给出了一个统计结果:
  优秀程序员的开发效率是普通程序员的 10 倍。40 多年过去了,这个数字得到了行业的普遍认同

备注

大多数人工作低效是由于工作中偶然复杂度太多造成的,只要能够更多地将注意力放到本质复杂度上,减少偶然复杂度造成的消耗,我们“真实”的工作效率自然会得到大幅度提升。

原则:

1. 以终为始
2. 任务分解
3. 沟通反馈
4. 自动化

重要

【本质】将精力聚焦在本质复杂度上,提高工作效率,摆脱直觉的束缚

思考框架

应届毕业生的培训思考三个问题:

1. 我现在是个什么水平?
2. 我想达到一个什么水平?
3. 我将怎样到达那个目标?

原来的问题是:
1. Where are we?(我们现在在哪?)
2. Where are we going?(我们要到哪儿去?)
3. How can we get there?(我们如何到达那里?)

本质是:
1. 现状
2. 目标
3. 实现路径

备注

如果一个人能够清晰地回答出这三个问题,通常意味着他对要做的事有着清晰的认识。这个框架虽然看似简单,但却非常有效

四个思考原则

当一个产品经理给我交代一个要开发的功能特性时,我通常会问他这样一些问题:

1. 为什么要做这个特性,它会给用户带来怎样的价值?
2. 什么样的用户会用到这个特性,他们在什么场景下使用,他们又会怎样使用它?
3. 达成这个目的是否有其它手段?是不是一定要开发一个系统?
4. 这个特性上线之后,怎么衡量它的有效性?

备注

衡量有效性,则是要保证我的工作不会被浪费。

备注

思考框架是为了让你明白为什么要提出问题,而具体问题要怎么问,就可以遵循下面这四项原则:1. 以终为始;2. 任务分解;3. 沟通反馈;4. 自动化。

以终为始就是在工作的一开始就确定好自己的目标。我们需要看到的是真正的目标,而不是把别人交代给我们的工作当作目标。你可以看出这个原则是在帮助我们回答思考框架中,Where are we going?(我们要到哪儿去?)这个问题

任务分解是将大目标拆分成一个一个可行的执行任务,工作分解得越细致,我们便越能更好地掌控工作,它是帮助我们回答思维框架中,How can we get there?(我们如何到达那里?)的问题。

沟通反馈是为了疏通与其他人交互的渠道。一方面,我们保证信息能够传达出去,减少因为理解偏差造成的工作疏漏;另一方面,也要保证我们能够准确接收外部信息,以免因为自我感觉良好,阻碍了进步。

自动化就是将繁琐的工作通过自动化的方式交给机器执行,这是我们程序员本职工作的一部分,我们擅长的是为其他人打造自动化的服务,但自己的工作却应用得不够,这也是我们工作中最值得优化的部分。

总结

  1. 以终为始:

    a) 遇到事情,倒着想
    b) 在做任何事之前,先定义完成的标准
    c) 在做任何需求或任务之前,先定好验收标准
    d) 尽早提交代码去集成
    e) 默认所有需求都不做,直到弄清楚为什么要做这件事
    f) 扩大自己工作的上下文,别把自己局限在一个 “程序员” 的角色上
    g) 在动手做一件事之前,先推演一番
    h) 问一下自己,我的工作是不是可以用数字衡量
    i) 设计你的迭代 0 清单,给自己的项目做体检
    
  2. 任务拆解:

    a) 动手做一个工作之前,请先对它进行任务分解
    b) 多写单元测试
    c) 我们应该编写可测的代码
    d) 将任务拆小,越小越好
    e) 按照完整实现一个需求的顺序去安排分解出来的任务
    f) 要想写好测试,就要写简单的测试
    g) 想要管理好需求,先把需求拆小
    h) 尽量做最重要的事
    i) 做好产品开发,最可行的方式是采用 MVP
    
  3. 沟通反馈:

    a) 通过沟通反馈,不断升级自己的编解码能力
    b) 用业务的语言写代码
    c) 多面对面沟通,少开会
    d) 多尝试用可视化的方式进行沟通
    e) 做好持续集成的关键在于,快速反馈
    f) 定期复盘,找准问题根因,不断改善
    g) 多走近用户
    h) 事情往前做,有问题尽早暴露
    i) 多输出,让知识更有结构
    
  4. 自动化

    1. 请谨慎地将工作自动化

    2. 将你的工作过程自动化

    3. 有体系地学习运维知识

    4. 将部署纳入开发的考量

    5. 将验收测试自动化

    6. 把函数写短

    7. 构建好你的领域模型

    8. 用简单技术解决问题,直到问题变复杂

    9. 学习领域驱动设计

  5. 综合运用:

    a) 了解一个项目,从大图景开始
    b) 小步改造遗留系统,不要回到老路上
    c) 在学习区工作和成长
    

一. 以终为始

任何事物都要经过两次创造:一次是在头脑中的创造,也就是智力上的或者第一次创造(Mental/First Creation),然后才是付诸实践,也就是实际的构建或第二次创造(Physical/Second Creation)。

人类是一个擅长脑补的群体,一旦有人看到了这个文档,他就已经可以构想出这个平台已经存在的样子,进而给出各种各样的反馈:“我认为这个地方可以这样做”“我觉得那个地方可以改改”。所有这些反馈都是真实的,因为他们已经“看到了”一个真实的东西。正是这些真实的反馈,让我们逐渐地锁定了目标。之后,我们才开始动手写代码。

备注

“以终为始”的方式,不仅仅可以帮我们规划工作,还可以帮我们发现工作中的问题。

找工作写简历:

1. 先确定我想要找到的工作是什么样的,
2. 然后收集很多招聘网站上给出的对应需求,整理划分成一份简历的技能树
3. 写好最终的简历
4. 按照简历上的要求去学习和提升

DoD

  • Definition of Done,完成的定义

  • 【定义】告诉我们怎样算是完成了,尽量减少因为理解偏差造成的各种浪费。

定义特点:

1. DoD 是一个清单,清单是由一个个的检查项组成的,用来检查我们的工作完成情况。
    DoD 的检查项,就是我们开发产品所需的一系列有价值的活动。
    比如:编写代码、编写测试代码、通过测试人员验收等。
    什么样的活动是有价值的,也许每个团队的认识是不同的。
2. DoD 的检查项应该是实际可检查的。
    你说代码写好了,代码在哪里;你说测试覆盖率达标了,怎么看到;
    你说你功能做好了,演示一下。
3. DoD 是团队成员间彼此汇报的一种机制。
别把 “汇报” 想复杂了,最简单的汇报就是说一句 “这个功能做完了”。
当我们有了 DoD,做事只有两种状态,即 “做完” 和 “没做完”。
在团队协作中,常听有人说 “事做完了 80%”,对不起,那叫没做完,根本没有 80% 做完的说法。

团队层面,我们也可以定义 DoD:

1. 某个功能的 DoD
  比如:这个功能特性已经开发完成,经过产品负责人的验收,处于一个可部署的状态。
2. 一个迭代的 DoD
  比如:这个迭代规划的所有功能已经完成。
3. 一次发布的 DoD
  比如:整个软件处于可发布的状态,上线计划已经明确。

备注

DoD 是一个思维模式,是一种尽可能消除不确定性,达成共识的方式。我们本着 “以终为始” 的方式做事情,DoD 让我们能够在一开始就把 “终” 清晰地定义出来。

备注

人与人协作中,经常会出现各种问题,根本原因就是,有太多因为理解差异造成的误解,进而浪费了大量的时间,而 DoD 就是一种将容易产生歧义的理念落到实处的方法。

例:

1. 和其他团队合作开发一个接口时,第一步就是要把接口定义下来。
    使用「模拟服务器的框架」快速固化接口定义
2. 工作生活中难免会有一些临时的工作,没有复杂到需要一个流程,但也可以用 DoD 思维来高效地解决

用户故事(User Story)

需求描述的问题

需求是软件开发的一个重要组成部分,但你可能并没有仔细想过,不同的需求描述方式,可能会影响我们程序员对需求的理解。因为信息的传递是会衰减的,你不可能把你理解的信息 100% 传递给另外一个人,而这中间,如何传递,也就是如何描述将直接决定衰减的比例。

用户故事大致包含以下几个部分:

1. 标题,简要地说明这个用户故事的主要内容
    比如:注册用户使用用户名密码登录。
2. 概述,简要地介绍这个用户故事的主要内容
    一般会用这样的格式:
    As a (Role), I want to (Activity), so that (Business Value).
    最重要的是,告诉别人为什么要做这件事,虽然只有一句话,却往往是很多人欠缺的思考,只知做,不知为何做
    例子:作为一个注册用户,我想要通过用户密码登录,以便我可以使用注册用户才能够使用的服务。
3. 详述,详细地描述这个用户故事的完整流程,我们会把操作流程、用户界面等信息都放到这里
    比如:
      用户使用正确用户名和密码登录,就可以登录成功;
      如果密码不正确,则登录页面提示用户 “用户名密码不正确”。
    超出范围的部分不做要求,这个部分主要是限定人们不要进一步发散。
    比如:第三方登录
4. 验收标准,这个部分会描述一个正常使用的流程是怎样的,以及各种异常流程系统是如何给出响应的
    这是程序员常常会欠缺的思考。
    它会把详述中很多叙述的部分变成一个具体的测试用例。
    比如:
      例:给定一个注册用户张三,其用户名是 zhangsan,密码是 foobar
      正常场景:当张三使用 zhangsan 和 foobar 登录系统时,可以成功登录
      异常场景:当张三使用 zhangsan 和 wrong 登录系统时,登录失败

备注

「用户故事」中最关键的一点就是 “验收标准”。验收标准中非常重要的一环是异常流程的描述。验收标准给出了这个需求最基本的测试用例,它保证了开发人员完成需求最基本的质量。(关联: BDD)

备注

如果你的团队采用用户故事的格式进行需求描述固然好,如果不能,在功能列表中,补充验收标准也会极大程度地改善双方协作的效率。

精益创业

备注

《精益创业》虽然这个名字里有“创业”二字,但它并不是指导人们创业挣大钱的方法论。正如前面所说,它要解决的是面向不确定性创造新事物。

创业领域是不确定性最强而且又需要创造新事物的一个领域,而只要是面向不确定性在解决问题,精益创业都是一个值得借鉴的方法论。比如,打造一个新的产品。

精益创业提出:

“开发(build)- 测量(measure)- 认知(learn)”这样一个反馈循环
和最小可行产品的概念

需要分清楚两件事,技术与需求:

要做什么是需求,能不能做是技术。
与产品经理要确认的是需求是否合理,
技术上能不能实现是技术团队要考虑的问题。

工作用数字衡量

备注

当今社会所面临的复杂度已经远远超过凭直觉就能把事情做好的程度。而当事情复杂到一定程度时,简单地靠感觉是很难让人相信的。

从数字中发现问题,让系统更稳定。

备注

建议用数字来发现问题和解决问题,但我不倾向用数字做为绩效。如代码量和 BUG 数,这些指标应该用来发现问题,而不是当作绩效标准。

答疑

  1. 领导要求的,无力反驳怎么办?:

    a) 管理上级的预期
    b) 帮助上级丰富知识(与上级同步共识)
    c) 说出你的想法(与上级同步想法)
    
  2. 别人能做的,我们也要做:

    a) 竞争对手有的产品,我们也要有
        “抄”不是问题,问题是无脑地抄。
    b) 人家能做到,说明技术上是可行的
        必须分清楚两件事:需求和技术。
    

总结

行业最佳实践:

1. DoD,确定好完成的定义,减少团队内部的理解不一致。
2. 用户故事,细化出有价值的需求。
3. 持续集成,通过尽早集成,减少改动量,降低集成的难度。
4. 精益创业,减少过度开发不确定性产品带来的浪费。
5. 迭代 0,在项目开始之前,做好一些基础准备。

思维转变:

1. 任何事物都要经过两次创造
    一次是在头脑中的创造,也就是智力上的或者第一次创造(Mental/First Creation)
    然后才是付诸实践,也就是实际的构建或第二次创造(Physical/Second Creation)
2. 在更大的上下文内发现自己的“终”
3. 通过推演,找到通往“终”的路径
4. 用可度量的“数字”定义自己的“终”

热门问题总结:

1. 作为程序员,你可以管理你的上级;
2. 拿老板说事的产品经理,你可以到老板面前澄清;
3. 喜欢无脑抄袭的产品经理,让他回去先想清楚到底抄的是什么;
4. 分清楚需求和技术,产品经理和开发团队各自做好各自的事。

其他

吴军老师讲的“工”字,上面是目标或者行业边界,下面是自己的现状,中间的边就是实现路径,人生主要就是要找到这条路径,下面的一条边代表基础和能力,越粗越好

各种思考框架,包括通用的如金字塔原理,各种领域套路,4c3p

金字塔原理:

在解决问题领域可能是这样的:
1. 目标导向,在这里也就是以始为终。思考自己的目标
2. 分类,也就是思考从当前位置到目标有哪些影响因子
3. 优先级,在这里其实是选择适合的方法
4. 解决问题

解决问题的具体方法那就该是:
5. 任务分解
6. 自动化
7. 沟通反馈

《高效能人士的七个习惯》

备注

SMART 原则一般是用来定义目标的,DoD 定义的是过程。Specific(具体),Measurable(可衡量),Attainable(可达到),相关性(Relevant),有明确截止日期(Time-based)

二. 任务分解

例子

  • 德雷克公式:美国天文学家法兰克・德雷克(Frank Drake)于 1960 年代提出的一个公式,用来推测 “可能与我们接触的银河系内外星球高等文明的数量”。德雷克公式最大的作用在于:它将一个原本毫无头绪的问题分解了,分成若干个可以尝试回答的问题。

  • 马斯克的任务分解:通过将宏大目标进行任务分解,马斯克才能将一个看似不着边际的目标向前推进。

评价用户故事的 INVEST 原则:

1. Independent,独立的
2. Negotiable,可协商的
3. Valuable,有价值的
4. Estimatable,可估算的
5. Small,小
6. Testable,可测试的

需求的估算:

首先要选择一个度量标准。
度量用户故事大小的方式有很多种:
1. 有人用 T 恤大小的方式,也就是 S、M、L、XL、XXL
2. 有人用费波纳契数列,也就是 1、2、3、5、8

估算的结果是相对的,不是绝对精确的
估算的过程也是大家加深对需求理解的过程

答疑

面对不了解的技术,我该如何分解任务?:

答案很简单,先把它变成你熟悉的技术

怎么把它变成你熟悉的技术:
答案是,做一次技术 Spike
    Spike 强调的重点在于快速地试,和调研的意思不太一样。
    既然是快速地试,就要在一定的时间内完成,
    比如,五人天,也就是一个人一周的时间,再多就不叫 Spike 了

Spike 的作用就在于消除不确定性

怎么做技术 Spike 呢?
1. 通过各种渠道,对要用的技术有了一些感性的认识,至少你已经知道这项技术是干什么的了。
2. 快速地完成教程上的例子,跟着教程走一遍,最多也就是半天的时间。
    之所以要快速地完成教程上的例子,是为了让你有一个直观的认识
3. 我们要确定两件事:这项技术在项目中应用场景和我们的关注点
    技术最终是要应用到项目中的,
    本着 “以终为始” 的原则,我们就应该奔着结果做,
    整个的 Spike 都应该围绕着最终的目标做。

反例:
  最近我们团队也用到了不了解的技术做项目,一开始先用不到一周的时间去了解,写 demo.
  又花了一周多写了一个简单一点的新项目,并且成功上线了。
  但是这个时候我只能说只是会用这个新技术,虽然使用起来很熟练,但是对他的底层原理还是不太了解。
  这个时候公司有一个老项目,功能比较复杂一些,因为这个老项目历史遗留问题比较多
  这时候老大发话了,大家要不试着用新的技术重构一遍吧!
  因为新技术还不够成熟,各种功能缺失,或是尚未提供,
    一些常用的组件都要自己一个个去实现,
    因为项目涉及到的功能比较多,也不太可能一个一个的去验证,
    这个时候也只有在做的时候才会暴露问题,所以一再延期。
  一开始评估的时候也知道新技术对这些功能都提供了支持,但是不清楚能支持到哪一步,
    到具体去实现的时候才发现很多坑,目前已经陷入这个项目三四个月了,
    感觉离完成瑶瑶无期啊,不知道老师有什么好的建议没。
作者回复: “怎么把新技术用在自己的项目中”,
  在这个问题中,很多人有一个严重的误区,他们眼中看到的更多的是 “新技术”,
    而我思考这个的逻辑在于 “自己的项目”。
  只有理解清楚了自己的问题,才好应用新技术去解决,
    盲目地采纳新技术,只会让自己不断地纠结,
    小程序库还好,要是引入一个大框架,无穷的问题就会吞噬你的时间。

项目时间紧,没时间写测试,该怎么办?:

经典误区:混淆了目标与现状
目标是应该怎么做,现状是我们正在怎么做

假设现在不忙了,你知道该怎么改进吗?

多个功能同时开发,同时上线,怎么办?:

这种问题的常见解决方案是Feature Toggle。

Feature toggle(功能开关)分享两篇文章:
https://martinfowler.com/articles/feature-toggles.html

https://www.infoq.cn/article/function-switch-realize-better-continuous-implementations

总结

最佳实践:

1. 测试金字塔
-- 行业中测试组合的最佳实践。
-- 多写单元测试是关键。
2. 测试驱动开发
-- 重构,重构是测试驱动开发区别于测试先行的关键。
-- 有人把测试驱动开发理解成测试驱动设计,它给行业带来的思维改变是,编写可测的代码。
3. 艾森豪威尔矩阵(Eisenhower Matrix)
-- 将事情按照重要和紧急进行划分。
-- 重要且紧急的事情要立即做。
-- 重要但不紧急的事情应该是我们重点投入精力的地方。
-- 紧急但不重要的事情,可以委托别人做。
-- 不重要不紧急的事情,尽量少做。
4. 最小可行产品
-- “刚刚好”满足客户需求的产品。
-- 在实践中,要用最小的代价找到一条可行的路径。

直接在工作中应用的做法和评判标准:

1. 尽量不写 static 方法
2. 主分支开发模型是一种更好的开发分支模型
3. 好的用户故事应该符合 INVEST 原则
4. 估算是一个加深对需求理解的过程,好的估算是以任务分解为基础的
5. 好的测试应该符合 A-TRIP

重要的思想:

1. 分而治之,是人类解决问题的基本手段
2. 软件变更成本,它会随着时间和开发阶段逐步增加
3. 测试框架把自动化测试作为一种最佳实践引入到开发过程中
    使得测试动作可以通过标准化的手段固定下来
4. 极限编程之所以叫“极限”,它背后的理念就是把好的实践推向极限
5. 大师级程序员的工作秘笈是任务分解,分解到可以进行的微操作
6. 按照完整实现一个需求的顺序安排开发任务

其他

我会的任务分解,不仅可执行,粒度还很细。比如说,我要修复一个 rpc 接口的 bug。我会列出每个代码的修改点,要修改的测试,要增加的测试,合并到哪个分支,修改 rpc 文档,文档中有哪些点要修改。 每一步都非常容易执行,看起来每多少必要,但在我当前的工作环境特别有用:1)事前思考,不会造成遗漏,2)任务实施过程中经常被打断,比如,测试有疑问和你讨论,主管找你谈事,紧急会议来了,这种 “硬中断” 完全打破了节奏,而任务列表,让我知道清楚当前做了多少,该从哪一步继续。

三. 沟通反馈

看板:

一种来自精益生产的可视化实践
按阶段将任务放置其中
可以帮助我们发现问题

持续集成:

1. 做好持续集成的关键是,快速反馈
2. 本地检查通过之后再提交
3. 找到有效的反馈方式,比如:CI 监视器
4. 持续集成的纪律
    只有 CI 服务器处于绿色的状态才能提交代码
    CI 服务器一旦检查出错,要立即修复

回顾会议:

1. 软件团队复盘的一种实践
2. 枚举关注点,选出重点,深入讨论,列出行动项,找到负责人

5 个为什么:

1. 又一个来自丰田的实践
2. 沿着一条主线追问多个问题

思路:

1. 用信息论理解沟通反馈
2. 写代码的进阶路径
    编写可以运行的代码
    编写符合代码规范的代码
    编写人可以理解的代码
    用业务语言写代码
3. 会议是一种重量级的沟通方式
    减少参会人数
    找人面对面沟通
4. 聆听用户声音
    能做自己用户,做自己的用户
    能接近用户,接近用户
    没有用户,创造用户
5. Fail Fast
    一种编写代码的原则
    出现问题尽早报错
6. 金字塔原理
    从中心论点,到分论点,再到论据

四. 自动化

持续交付:

1. 将生产部署纳入了开发的考量
2. 持续交付的基础设施通常包含持续集成环境、测试环境、预生产环境和生产环境
3. 构建流水线保证到了下游的交付物一定是通过上游验证的
4. 随着 Docker 的诞生,交付由发布包变成了 Docker 镜像

DevOps:

将开发和运维结合到一起
环境配置工具上的进步,让基础设施即代码成了行业共识

验收测试:

1. 验收测试要站在业务的角度编写
2. BDD 是一种编写验收测试的方式
3. Given...When...Then... 的描述给了一个描述业务的统一方式
4. 写好验收测试,需要构建测试模型

SOLID 原则:

设计模式背后的道理
单一职责原则(Single responsibility principle,SRP)
开放封闭原则(Open–closed principle,OCP)
Liskov 替换原则(Liskov substitution principle,LSP)
接口隔离原则(Interface segregation principle,ISP)
依赖倒置原则(Dependency inversion principle,DIP)
用好单一职责原则,前提条件是看待问题颗粒度要小

DDD:

1. 它将思考的起点拉到了业务上
2. DDD 分为战略设计和战术设计

微服务:

1. 做好微服务的前提是划分好限界上下文
2. 微服务的第一步,不要划分微服务

思路:

1. 程序员的三大美德:懒惰、急躁和傲慢(Laziness, Impatience and hubris)
2. 小心 NIH 综合症(Not Invented Here Syndrome)
3. 写好构建脚本,做好项目自动化
4. 参照 Java 知识体系,学习运维知识
5. 软件设计最基础的原则是 “高内聚、低耦合”
6. 分层架构是一种设计上的分解
7. 不同业务量的系统本质上不是一个系统
8. 采用简单技术解决问题,直到问题变复杂

五. 综合运用

面对遗留系统,稳扎稳打,小步前行:

基础理念
    1. 烂代码只是现象,要了解根因
    2. 能重构,先重构,大规模改造是迫不得已的选择
    3. 小步前行
实际操作
    1. 构建测试防护网
    2. 将大系统分解成小模块,逐步替换
    3. 新旧模块并存,由分发模块调度
    4. 建立好领域模型
    5. 寻找行业对于系统构建的最新理解

“学习区”学习模型:

1. 舒适区,舒适而缺乏成长
2. 恐慌区,超出能力范围
3. 学习区,有难度而可以达成

T 型人才,一专多能:

1. 知识的广度
2. 专业技能的深度
3. 有“一专”,“多能”才是有意义的

有了“一专”,拓展“多能”:

1. 如果还能够带着其他人一起做好,就成了技术领导者
2. 如果能够分享技术的理解,就有机会成为培训师
3. 如果能够在实战中帮助别人解决问题,就可以成为咨询师

进入新工作,从全面了解开始:

1. 业务:做什么
2. 技术:怎么做
3. 团队运作:怎么与人协作
4. 从大到小,由外及内地了解工作

好书推荐

编码实践

如果你想详细学习如何写好代码,我推荐你去读 Robert Martin 的《代码整洁之道》(Clean Code),这本书几乎覆盖了如何把代码写好的方方面面。 《实现模式》是一本关于如何写好代码的书,更具体一点是,编写别人能够理解的代码。它的作者 Kent Beck 是许多软件开发实践的开创者。但 Kent Beck 的写作能力一般,他的很多作品被埋没了。只有细细品味,才能体会到 Kent Beck 深厚的功力。 我提升自己编码水平的理解是从《程序设计实践》(The Practice of Programming)这本书开始的,这本书的作者是 Brian Kernighan 和 Rob Pike,这两个人都出身于大名鼎鼎的贝尔实验室,参与过 Unix 的开发。 如果你想从日常开发中提升自己的效率,可以读一下《卓有成效的程序员》。假如你不曾思考过这个问题,这本书会让看到一些不同的工作方式,我也给这本书写过一篇书评。不过,这本书里的技巧太具体了,所以,有一些已经有些过时了。

设计

SOLID 原则是一种面向对象软件设计原则。早在 1995 年,Robert Martin 就提出了这些设计原则的雏形,然后在他的《敏捷软件开发:原则、实践与模式》这本书中,比较完整地阐述了这五个原则,后来,他有把这些原则进一步整理,成了今天的 “SOLID”。有了设计原则做基础,这本书后面讲了设计模式,理解起来就容易多了。虽然书名是关于敏捷的,但这是一本讲设计的书。 设计和架构有什么区别?2017 年,Robert Martin 出版了《架构整洁之道》(Clean Architecture),他在其中告诉我们,二者没有区别。所以,这也是一本关于设计的书,给出了 Robert Martin 对设计的最新理解。你可以把它看成《敏捷软件开发:原则、实践与模式》的修订版。 《设计模式》不推荐阅读,它是设计模式的开山之作,但它的起点是 Erich Gamma 的博士论文,其写作风格偏向学术,而且中文版翻译得也很一般。这里将它罗列出来只是因为其历史重要性。如果你想学习设计模式,现在有一些更容易入门的书,比如《Head First 设计模式》。 Martin Fowler 的《企业应用架构模式》将软件开发当时常见的解决方案汇集成模式,今天看来很多模式已经习以为常,但当年出场可是技惊四座的。从这本书的名字你不难看出,它出版的年代是企业级开发盛行的年代。Martin Fowler 一直认为这本书没有写完,希望能够继续更新,但不知道何时能看到这本书的新版。 《Unix 编程艺术》也是一本讲软件设计的书,只不过,它选择的切入点是 Unix 中的设计,从中你可以学到“只做一件事,把它做好”、“文本化”等编程理念,有助于你改善日常的工作。这样的书,也就只有 Eric Raymond 这样沉浸编程几十年的人才能写出来。

工程实践

Kent Beck 有一本知名的软件工程之作《解析极限编程》(Extreme Programming Explained),它介绍了一种软件开发方法:极限编程。但更重要的是,今天很多主流的软件开发最佳实践都是从这里出来的。这本书可以理解成诸多最佳工程实践的总纲。 Martin Fowler 在 1999 年写下软件行业的名著《重构:改善既有代码的设计》(Refactoring: Improving the Design of Existing Code),把重构这个小圈子实践带到了大众视野。2018 年底,Martin Fowler 时隔近 20 年后,又写出了《重构》第二版。把他对这些年行业发展的新理解融入到重构实践中。重构应该有个目标,这个目标就是“重构成模式”,而这也是一本专门的书:《重构与模式》(Refactoring to Patterns)。 《测试驱动开发》是 Kent Beck 为世人展示 TDD 做法的一本书。它好的地方需要自己体会,Kent Beck 并没有显式的讲出来,比如:任务分解。 Jez Humble 和 Dave Farley 的《持续交付》(Continuous Delivery)让持续集成再进一步,将生产环境纳入了考量。乔梁,他是《持续交付》这本书的中文版译者,而且在这本书出版近十年后,他自己写了《持续交付 2.0》,把自己多年来关于持续交付的新理解整理了进去。 说到遗留代码和测试,我推荐一本经典的书:Michael Feathers 的《修改代码的艺术》(Working Effectively with Legacy Code),从它的英文名中,你就不难发现,它就是一本关于遗留代码的书。如果你打算处理遗留代码,也建议你读读这本书。这本书我也写过书评,你可以了解一下我对它看法。

领域驱动设计

Eric Evans 2003 年写了《领域驱动设计》,向行业介绍一下 DDD 这套方法论,立即在行业中引起广泛的关注。但实话说,Eric 在知识传播上的能力着实一般,这本关于 DDD 的开山之作,其写作质量却难以恭维,想要通过它去学好 DDD,是非常困难的。所以,在国外的技术社区中,有很多人是通过各种交流讨论逐渐认识到 DDD 的价值所在,而在国内 ,DDD 几乎没怎么掀起波澜。 2013 年,在 Eric Evans 出版《领域驱动设计》十年之后,DDD 已经不再是当年吴下阿蒙,有了自己一套比较完整的体系。Vaughn Vernon 将十年的精华重新整理,写了一本《实现领域驱动设计》,普通技术人员终于有机会看明白 DDD 到底好在哪里了。所以,你会发现,最近几年,国内的技术社区开始出现了大量关于 DDD 的讨论。 因为《实现领域驱动设计》实在太厚,Vaughn Vernon 又出手写了一本精华本《领域驱动设计精粹》,让人可以快速上手 DDD,这本书也是我向其他人推荐学习 DDD 的首选。

产品与需求

精益创业是 Eric Ries 最早总结出来的。他在很多地方分享他的理念,不断提炼,最终在 2011 年写成一本同名的书:《精益创业》。如果说精益创业是理论,《精益创业实战》这本书则给了你一个操作流程。 Mike Cohn 是敏捷理念的一个重要传播者,我们在讲测试金字塔时,提到了他的著作《Scrum 敏捷软件开发》(Succeeding with Agile)。敏捷开发有两大流派:一派是工程实践,另一派是管理实践。如果你对 Scrum 这类管理实践感兴趣,可以读一下这本书。 如果你对用户故事这个话题感兴趣,推荐阅读 Mike Cohn 的两本书《用户故事与敏捷方法》(User Stories Applied)和《敏捷软件开发实践 估算与计划》(Agile Estimating and Planning)。

开发文化

软件行业里有一本名著叫《人月神话》,这算是软件开发领域第一本反思之作。今天,我们讨论的很多词汇都出自这本书,比如,没有银弹、焦油坑等等。虽然这本书出版于 1975 年,但其中提到的问题,依然困扰着今天的程序员。 开源概念的提出者 Eric Raymond,他的《大教堂与集市》推开了开源大门。今天开源软件已经成为程序员日常工作的一部分,但如果没有 Eric Raymond 这些人的努力,我们还必须与复杂的企业级软件搏斗。了解一下开源的历程,可以帮助你更好地理解今天的幸福。 程序员应该如何做,Robert Martin 也写了一本书《程序员的职业素养》(Clean Coder),其中对大多数程序员最重要的一点建议是,说“不”。 软件开发拾遗 高德纳的《计算机程序设计艺术》肯定是一套程序员都知道,但没几个人读完的书。算法的讲解经过几十年已经有了很好的发展,如果学算法,肯定有更好的选择。如果你想看图灵奖获得者如何从根上思考问题,不妨找来这套书来翻翻。 《快速软件开发》(Rapid Development),不推荐阅读。在这本书中,作者首次提出了解决集成问题的优秀实践:Daily Build,每日构建。通过这个名字,我们便不难看出它的集成策略,即每天集成一次。它其中很多实践在当时是先进的,但今天看来有些落伍了。如果你只想从中收获一些理念性的东西,可以去读读。 《C 程序设计语言》、《Unix 编程环境》等出自贝尔实验室大师级程序员之手,他们的书都值得一读,其中的内容今天看来可能有些过时,但他们解决问题的方式和手法却值得慢慢品味。 我在讲淘宝技术变迁时,提到了《淘宝技术这十年》,这本书算不上经典,但可以当做休闲读物。

技术之外

管理大师彼得·德鲁克有一本经典著作《卓有成效的管理者》,虽然标题上带着管理者几个字,但在我看来,这是一本告诉我们如何工作的书,每个人都可以读一下。 尤瓦尔·赫拉利的《人类简史》或《未来简史》,是我第一次学到“大历史观”这个说法,历史不再是一个个单独的历史事件,而是一个有内在逻辑的发展脉络。 《从一到无穷大》是一本著名科普著作,它向我们介绍了 20 世纪以来的科学进展。作者乔治·伽莫夫既是热宇宙大爆炸模型的提出者,也是生物学上最早提出“遗传密码”模型的人。虽然这本书出版自 1947 年,但以现在社会的整体科学素养,还是有必要读读这本书的。 史蒂芬·柯维(Stephen Richards Covey)的《高效能人士的七个习惯》,其中的理念我在专栏两个不同的地方提到过,一个是讲以终为始时,那段关于智力创造的论述,另一个是讲优先级时提到的艾森豪威尔矩阵。这本书值得每个人阅读,很多程序员欠缺的就是这些观念性的东西。 很多程序员都是科幻小说迷,编程和科幻,这两个都是需要想象力的领域。刘慈欣的《三体》,不说它给 IT 行业带来的丰富的词汇表吧,作为科幻小说来说,它就是一流的,值得阅读。它会让你仰望星空,打开思维。如果你对科幻小说有兴趣,推荐阅读阿西莫夫的《银河帝国》系列,这是科幻小说界的扛鼎之作,你会看到,一部出版于 1942 年的书里就有大数据的身影。 对于程序员来说,最好的工作状态就是进入心流,它会让你忘我工作。如果你对心流的概念感兴趣,可以去读米哈里·契克森米哈赖的著作《心流》,这位作者就是心流概念的提出者。

提问

直觉在某种程度上也是很重要的吧,不是很多专家都是很依赖直觉的么 作者回复:这是一个好问题,这种说法混淆了直觉和洞见两件事。直觉是本能的,无需积累,而洞见是溯因推理(Abductive Reasoning),需要前期进行大量的积累之后,从中发现模式,方能形成洞见。

主页

索引

模块索引

搜索页面