读书笔记:活文档

第1章 重新思考文档  1

1.1 一则来自活文档世界的故事 1
1.1.1 为什么需要这个功能 1
1.1.2 明天你就不再需要这个草图了 2
1.1.3 抱歉,我们没有营销文档 2
1.1.4 你一直在用这个词,但并非其本意 3
1.1.5 给我看看完整的图,你就知道哪里有问题了 3
1.1.6 活文档属于未来?不,是现在 4

1.2 传统文档存在的问题 4

1.2.1 编写文档通常不太酷 4

1.2.2 文档的缺陷 5

1.独立活动
活动相互独立会导致大量浪费并丧失机会。基本上,所有的活动都会用到相同的知识,只是以不同的形式和工件来使用,并且可能伴有一定程度的重复。另外,在流程中,这些“相同”的知识可能会演进发展,从而导致不同活动中的知识内容不一致。

3.冗余知识
不幸的是,当一个工件 (例如代码)发生变化时,你很难记得要更新其他文档。于是,文档内容很快就过时了。

9.信息墓地
企业知识管理解决方案是知识消亡的地方。看看这些:

  • 企业wiki
  • SharePoint
  • 大型Microsoft Office文档
  • 共享文件夹
  • 搜索功能很差的工单系统和wiki

要么是因为通过它们很难找到正确的信息,要么是因为将信息保持最新状态需要大量工作,或者两者皆有。这些方法促进了只写文档( write-only
documentation)或只写一次文档 ( write-once documentation)的形式。

1.2.3 敏捷宣言与文档 9
1.2.4 是时候开启文档2.0 了 9

1.3 文档编写的是知识 10

软件开发过程需要知识,并需要基于这些知识做出决策,而这些决策反过来又创造了新的知识。

在软件开发中,设计阶段之后不会有昂贵的构造阶段:构造(运行编译器)非常便宜,昂贵的只有一个设计阶段(有时候是长久存在的)。

知识缺失会导致两种后果。

  • 浪费时间:这些时间本可以更好地投人到其他方面的改进上。
  • 次优决策:从长远来看,其他决策可能更有意义或成本更低。

1.3.1 知识的来源 11
1.3.2 知识如何演进 11
1.3.3 为什么需要知识 11
1.4 文档是为了传递知识 14

1.5 活文档的核心原则 15

  • 可靠:无论何时,活文档都是准确的,并且与所交付的软件保持同步。
  • 省力:活文档最大限度地减少了文档工作量,即使是软件发生了变更、删减或添加仅需极少的额外工作,而且只需要操作一次。
  • 协作:活文档可以促进所有参与者之间的对话和知识共享。
  • 有见地:活文档会将人们的注意力引导到工作的各个方面,从而提供反馈机会并鼓励深入思考。它能帮助你反思正在进行的工作并做出更好的决策。

1.5.1 可靠 16
1.5.2 省力 16
1.5.3 协作 17
1.5.4 有见地 17
1.5.5 蚂蚁怎么交换知识:共识主动性 18
1.6 大部分知识是已经存在的 18

1.7 固有文档 19

存储文档的最佳位置是被记录的事物本身。

在飞机上,中间走道上的明亮标志指示去向。在危急情况下你没有时间去找手册,答案需要位于最明显的地方:你当前所在的位置,也就是事物本身上。

1.7.1固有文档 与外部立地

如果知识被编写成外部文档,那么文档的形式与你所选择的项目实现技术将完全无关。传统形式的文档就是这种情况,即共享文件夹里存着的独立Microsoft Office文档或带有数据库的Wiki站点。

它们的缺点是,要确保与产品版本保持同步更新非常困难(尽管也有可能做到),而且很容易丢失。

固有文档的一个良好示例是:在语言标识符上使用Java注解或命名约定来声明和解释设计决策。

固有文档的缺点是你的知识表达受限于语言内置的扩展机制。另一个很大的缺点是,非开发人员不容易获得固有文档记录的知识。但是,我们也可以通过自动化机制来解决这个限制。这种自动化机制可以提取知识并将其转换为目标受众可以访向的文档。

1.7.1 固有文档与外部文档 20

1.7.2 固有文档与外部文档示例 20

1.7.3 固有文档 21

1.7.4 就地文档 21

1.7.5 机器可读的文档 22

1.8 专门知识与通用知识 22

1.8.1 学习通用知识 22

1.8.2 专注于专门知识 23

1.9 确保文档准确 23

仅当能通过机制保证文档的准确性时,你才能信任文档。

1.9.1 准确性机制保证文档可靠 23

1.单一来源发布机制
例如,源代码和配置文件通常是大量知识的天然权威来源。手动编写文档经常会引人一些错误,而自动化发布则可以避免类似问题发生。

3.具有一致性机制的冗余源
带有自动化工具的BDD (例如Cucumber )是这种方法的一个示例。每当运行场景的测试失败时,就表明场景和代码不再同步。

1.9.2 当文档不需要准确性机制时 25

1.10 挑战文档的大问题 25

1.10.1 质疑是否真的需要文档 26

1.10.2 因缺乏信任而需要文档 26

需要细节可能意味着缺乏信任

1.10.3 即时文档,或者未来知识的廉价选择 27

1.10.4 质疑是否需要传统文档 28

1.10.5 减少现在的额外工作 29

1.10.6 减少以后的额外工作 29

1.11 让活动变得有趣 30

1.12 文档重启 31

1.12.1 活文档:非常简短的版本 35

1.12.2 更好的文档编制方法 35

  • 自动化文档:自动化文档是最“极客”的操作,是指使用特定工具,并根据软件结构的变化,以“活的”方式自动生成文档。

1.13 DDD入门 36

1.13.1 DDD概述 36

1.13.2 活文档和DDD 36

1.13.3 当活文档是DDD应用时 37

1.13.4 BDD、DDD、XP和活文档同根而生 37

1.14 小结 39

第2章 BDD:活需求说明的示例 40

2.1 BDD是为了对话 40

2.2 实现自动化的BDD是为了活文档 41

冗余与一致性
BDD场景描述的是应用程序的行为,但是应用程序的源代码描述的也是同样的行为,所以场景和源代码彼此冗余。

因此,我们需要一种致性机制。对于BDD,你可以使用测试和Cucumber或SpecFlow等工具来保障一致性。这些工具就像罗伯威尔结构样在两个冗余知识之间实现平衡。

2.3 在文件中解析场景 42

2.3.1 功能文件的意图 42

2.3.2 功能文件场景 43

2.3.3 需求说明的细节 43

2.3.4 功能文件中的标签 44

标签就是文档。一些标签描述了项目管理知识,例如@wip代表“Work in progress",即工作正在进行中,表示当前正在开发此场景。或者提及冲刺(例如,@sprint-23)

在《实例化需求:团队如何交付正确的软件》一书中, Gojko Adzic列出了三种将信息整理成文件夹的方法:

  • 按功能领域
  • 根据UI导航路径(当记录用户界面时)
  • 根据业务流程(当端到端用例的可追溯性是必需的)

通过这种方法,文件夹的名称就代表了业务文档的各章(如本章后面的示例所示)。

2.3.5 场景即交互式活文档 45

场景构成了活文档的基础。更好的是,这种文档一般是交互式的,就像生成的一个交互式网站。例如,如果结合使用Pickles和SpecFlow,则每个构建过程都会生成个特定的单页网站。

2.3.6 将场景做成无聊的纸质文档 46

像上节所示的交互式网站对于团队来说很方便,可以快速访向业务行为知识。但是,在某些情况下(例如有强制合规性要求时).你必须提供无聊的纸质文档( boring paper document,有些人称之为BPD)。

Tatziki,因为它是种黄瓜酱的名字。它能从功能文件中导出漂亮的PDF文档,更进一步,它还能导出Markdown文件,并能将与功能文件起存储导出到文档里。

2.4 功能文件示例 46

2.5 用典型案例展示活文档的方方面面 48

2.6 更进一步:充分利用活文档 48

支持团队执行BDD实践的大多数工具支持Gherkin语法。使用这种工具时,功能文件最好采用如下所示的固定格式:

1 Feature: 功能名称
2
3 为了....作为一名....我想.....
4
5 Scenario: 第一个场景的名称
6 Give.....
7 When......
8 Then.....
9
10 Scenario: 第二个场景的名称
11 ....

所以,他们开始在两者之间(即“描述区域”)添加对业务案例的额外描述,这些描述会被工具无视。像Pickles这种能根据功能文件生成文档的工具适应了这种用法,并开始为所谓的“描述区域”支持Markdown格式:

1 Feature: 投资现值
2
3为了计算投资机会的盈亏平衡点
4作为一名投资经理
5我想要计算未 来现金的現值
6
7
8 描述
9 =============
10

2.7 小结 51

第3章 知识开发 52

因为知识已经存在于多个地方,所以你需要做的只是建立一种机制, 以便在需要某个知识时,将它从所存储的地方提取出来,并放到需要它的地方。另外,由于你没有太多时间做这件事情,这个机制必须是轻量级的、可靠的和省力的。

3.1 识别权威性知识 52

3.2 知识现在在哪里 52

3.3 单一来源发布 53

让知识只有单一信息源,并在需要时以该来源的内容为准发布知识,这一点很重要。

因此,每一项知识都只放在一个地方,使其成为权威性知识来源。当文档受众无法直接访问这些知识,而你又必须为他们提供这些知识时,请从该单-知识来源发布文件。不要通过复制和粘贴的方法将知识元素包含到要发布的文档中,而是使用自动化机制直接从单一的权威性知识来源创建需要发布的文档。

3.3.1 制作并发布文档的示例 54

能从源代码和其他技术工件中创建文档的工具有很多,

  • GitHub: GitHub会将README.md文件转换为漂亮的网页。
  • Javadoc: Javadoc 提取了代码的结构以及所有公共或私有API, 并将其作为参考文档发布到网站上。
  • Leanpub: 每一章内容对应一个独立的Markdown文件,图片保存在外部,代码可以在它们自己的源文件中,甚至目录也在其自己的文件中。Leanpub 的发布工具链就会根据目录整理所有文件,并通过各种工具对Markdown文件进行渲染、排版和代码突出显示,从而生成PDF、MOBI和ePUB等格式的高质量图书。

3.3.2 发布一个带版本号的快照 55

3.3.3 备注 55

3.4 设置一致性机制 55

3.4.1 运行一致性测试 56

3.4.2 关于测试假设的一致性 57

3.4.3 发布的约定 58

3.5 整合分散的信息 59

3.5.1 如何整合知识 60

3.5.2 实施整合的注意事项 61

3.6 现成的文档 61

  • Kent Beck的《测试驱动开发》
  • Erich Gamma、John Vissides、 Ralph Johnson和Richard Helm的《设计模式:可复用面向对象软件的基础》
  • Martin Fowler的《企业应用架构模式》
  • Eric Evans的《领域驱动设计:软件核心复杂性应对之道》
  • C2 wiki上的所有内容
  • Jerry Weinberg的每一本书
  • Jez Humble和DuiFardey的《持续交付:发布可靠软件的系统方法》
  • 所有描述简洁代码的文献
  • Git工作流策略

可以肯定地说,只要你能想到的,都已经有人写过了。即使你还不知道一些模式、标准名称和标准做法,它们也已经存在了。

成熟商业行业里的知识也是通用知识。即使在竞争激烈的领域(如金融定价或电子商务中的供应链优化)中,大多数知识也是公开的,并且可以在行业标准书籍中获得。

例如,每个业务领域都有自己必不可少的书单,而且可能都有一本书会被称为该领域的“圣经”,例如John C. Hull的《期权、期货和其他衍生品》和Martin Christopher 的《物流与供应链管理》。

通用知识记录的都是已经解决的问题。这些知识是现成的,可供所有人重复使用。如果你已经在系统里应用了这些通用知识,那么只需要链接到正确的文献就可以完成文档编写。

因此,想象一下,大多数知识已经记录在行业文献的某个地方了。自己学习,或者从网络上寻找知识的权威性来源,或者向其他行家咨询。对于别人已经写好的内容,不要试图再记录一遍,做个链接就可以了。也不要试图原创,而要尽可能采用标准实践和标准词汇。

3.6.1 标准词汇的力量 63

控制了词汇的人就控制了思想。路德维希.维特根斯坦

与世界上其他所有人用相同的词来交谈是一个绝佳的优势。 它使你能用更短的句子进行交流。

3.6.2 链接到标准知识 64

3.6.3 不仅仅是词汇 64

3.6.4 在会话中使用现成的知识来加速知识传递 65

3.7 工具历史 68

以下是一些工具及其知识的示例。

  • 源码控制系统:Git
  • 内部聊天系统:slack

3.8 小结 69

第4章 知识增强 70

4.1 当编程语言不够用时 70

实际上,你可以使用以下几种方法来增强代码:

  • 固有文档
    • 使用注解
    • 按照约定
  • 外部文档
    • 使用边车文件
    • 使用元数据数据库
    • 使用DSL

4.2 使用注解编写文档 72

在注释中使用结构化标签
如果你使用的是没有注解功能的编程语言,那么可以在注释中使用结构化标签:

/** @Adapter */

4.2.1 注解不只是标签 73

4.2.2 描述决策背后的依据 74

4.2.3 嵌入式学习 74

4.3 按照约定编写文档 77

4.3.1 使用约定的遗留代码中的活文档 78

4.3.2 记录约定 78

4.3.3 始终遵守约定 79

4.3.4 约定的局限性 79

4.4 外部文档编写方法 80

使用注解和的定编写的文档是固有文档的形式,它们直接出现在代码中。相反,以下各节中描述的技术是外部文档的形式,因为它们远离被记录的事物。

4.4.1 边车文件 80

如果无法在代码中添加注解,那么可以将它们写成一个文档,放在代码文件旁边。边车(sidecar file,也称为伙伴文件、伴侣文件或连接文件)就是用于存储源文件格式不支持的元数据的文件。对于每个源文件,通常会有一个关联的边车文件,它们名称相同,但扩限名不同。

4.4.2 元数据数据库 80

4.5 设计自定义注解 81

4.5.1 构造型的属性 81

4.5.2 构造型和战术模式 82

4.5.3 注解包名称要有意义 83

4.5.4 强行将标准注解移作他用 83

4.5.5 标准注解:@Aspect和面向切面编程 84

4.5.6 默认注解或除非必要 85

4.6 处理全模块知识 85

4.6.1 处理多种模块 86

4.6.2 在实践中进行全模块增强 86

4.7 固有知识增强 87

4.8 机器可访问的文档 88

4.9 记录你的决策依据 90

4.9.1 依据里有什么 91

  • 当时的背景:
  • 选择背后的问题或要求:
  • 有一个或多个主要原因的决策本身(而不是选择的解决方案):
  • 认真考虑的主要替代方案,不选择它们的原因,或者在背景不同的情况下会选择它们的原因:

通常来说,设计依据在很大程度上与丢弃的选项有关,因此它通常不会在代码里。
决策依据是根据实际需求所做出的决定, 而这些需求已被证明是必要的。我们仅在有必要构建时才进行构建。

4.9.2 使依据明确 92

4.9.3 超越文档:被激发的设计 92

4.9.4 避免记录猜测 92

4.9.5 作为预记录依据的技能 93

4.9.6 将依据记录作为推动变革的因素 93

4.10 确认你的影响力(又名项目参考文献) 94

4.11 将提交消息作为全面的文档 95

1.指定变更的类型
type (类型)必须是以下之一。

  • feat:一项新功能。
  • fix:一个bug修复。
  • docs:仅文档变更。
  • style:不影响代码含义的变更,例如对空格、格式、缺失分号等的变更。
  • refactor:既不修正bug也不增加功能的代码变更。
  • perf:改善性能的代码变更。
  • test:添加缺失测试的变更。
  • chore:更构建过积成辅助工具和单,例如文村生成。

3.机器可理解的信息
根据Angular.js的约定,每个版本的变更日志都由三个可选部分组成,并且每个部分仅在仅在为空时才显示

  • New Features (新功能)
  • Bug Fixes (bug修复)
  • Breaking Changes (重大变更)

发布时,脚本可以生成此处显示的变更日志。许多开源项目可以做到这一点,例如conventional-changelog项目。

4.12 小结 98

第5章 活知识管理:识别权威性知识 99

5.1 动态的知识管理 99

在艺术展览中,策展人就像电影导演一样重要。在当代艺术中,策展人要选择艺术品并经常、对它们进行诠释。例如,策展人会寻找那些激发了艺术家灵感的作品和地方,然后通过叙事或结构化分析,以超越单个作品的方式将选定的作品联系起来。如果对展览至关重要的作品不在收藏中,策展人会从另一个博物馆或私人收藏中借用它,甚至可能委托艺术家创作。除挑选作品外,策展人还负责撰写标签和目录文章,并监督展览的现场布置,以帮助传达所选择的信息。
在文档编写领域,我们需要成为我们自己的策展人,利用已有的所有知识并将它们变成有意义和有用的内容。

因此,要用策展人的思维方式从源代码和工件的所有可用知识中挖出有意义的故事。不要选择固定的元素列表,而是依靠每个工件中的标签和其他元数据来动态选择长期关注的知识的内聚子集。当缺少必要的元数据时,增强代码,并在故事需要时添加所有缺失的知识。

解决方法就是针对特定的沟通意图积极地从噪声中滤除信号。正如图5-1中的小丑怪兽说的:“信息太多等于没信息。”一个信息,从一个角度来看是噪声,从另个角度来看, 可能就是个信号。

5.1.1 动态知识管理的示例 100

5.1.2 需要编辑的知识管理 101

5.1.3 不太需要维护的动态知识管理 101

5.1.4 一库多用的知识语料库 102

5.1.5 场景摘要 102

5.2 突出核心 103

5.3 突出启发性的范例 104

5.4 导览和观光地图 106

5.4.1 创建观光地图 108

5.4.2 创建导览 109

5.4.3 创建活导览 111

5.4.4 一个可怜人的文学式编程 112

5.5 总结:策展人筹备一场艺术展览 113

5.5.1 选择和整理现有知识 113

5.5.2 在需要时添加缺失的东西 114

5.5.3 使无法到场和以后的人可以访问 114

5.6 小结 114

第6章 自动化文档 115

6.1 活文档 115

活文档的工作方式类似于能在每次变更后都生成新报告的报告工具。这种变更一般是代码变更,但也可能是对话时做出的关键决定。

6.1.1 创建活文档的步骤 115

创建活文档通常需要四个主要步骤。
(1)选择存储在某处的系列数据, 例如源代码控制系统中的源代码。
(2)根据文档目标过滤数据。
(3)对于通过过滤器得出的每条数据,提取能用于文档的内容子集。它可以看作一幅投影图
像,而且特定于绘制图表。
(4)将数据及其中的关系转换为目标格式以生成文档。对于可视文档,这个目标可以是对渲
染库API的一系列调用;对于文本文档,它可以是工具生成PDF需要的文本片段列表。

6.1.2 演示规则 116

6.2 活词汇表 116

6.2.1 活词汇表是如何起作用的 117

6.2.2 请举个例子吧 117

6.2.3 活文档的信息管理 119

6.2.4 在限界上下文中创建词汇表 121

6.3 活图表 125

6.3.1 用图表协助对话 126

6.3.2 一图一故事 126

图表的大小是有限的,其受众的时间和认知资源也是有限的,这是一个图表应该只传达一个信息的主要原因。

因此,请记住,每个图表都应该有一个目的,而且只能有一个目的。抑制在现有图表中添加额外信息的冲动。如果真的有需要,另外为这些额外信息新建一个图表,并删掉那些对这个新图表没什么价值的信息。 主动过滤多余的信息,只有必不可少的元素才值得将其制作成图表。

6.3.3 活图表让你诚实 128

6.3.4 追求完美的图表 128

6.3.5 渲染活图表 129

渲染图表的工具有很多,但没有几个工具可以对任意图形进行智能布局。Graphviz 可能是最好的, 但它是一个本机工具。

谈谈工具
一些能帮 助渲染活图表的工具和技术包括Pandoc、 D3.js、Neo4j、AsciiDoc、PlantUML、ditaa、Dexy。

我们根据布局复杂度看-下图表类型。

  • 表格(表格可能不是真正的图表,但是它们有严格的布局)。
  • 固定在背景上的大头针(例如Google地图上的标记),它提供了一种方法,能将每个元素根据(x, y)位置固定在背景上。
  • SVG、DOT等图表模板,它们使用源代码中提取出来的实际内容进行评估。
  • 简单的一维流程图( 从左到右或从上到下),它们的布局简单,你甚至可以自己编程完成。
  • 管道图、序列图和进出生态系统黑盒。
  • 树状结构(从左到右,从上到下或放射状),它们可能很复杂,但是如果你真的想做,也可以自己做。
  • 继承树和图层。
  • 包含图,包含自动布局,例如使用Graphviz的集群功能。
  • 丰富的布局,带有垂直和水平布局以及包含图。

6.3.6 可视化准则 132

为什么这么多工程师认为复杂的系统图会令人印象深刻呢?真正令人印象深刻的是那些针对难题的简单解决方案。-@nahanmarz
终极经验法则:只要图表中有一条线与另一条线交叉,这个系统就过于复杂。-@pavlobron

  • 使自左向右和自上而下的轴有意义:示例可能包括从左到右的因果关系(左侧的API 和右侧的SPI),以及从上而下的依赖关系。
  • 使布局有意义:例如,元素之间的接近度可能意味着“相似度",而包含图可能意味着“专业化”。
  • 使大小和颜色有意义:例如,视觉元索的大小或颜色可能反映了其重要性、严重性或某些属性的规模。

6.3.7 示例:六边形架构的活图表 136

4.这些知识现在哪里

给制六边形架构时使用的一个方便约定是,将消耗领城模型的所有元素都放在左侧,而为领度型提供服务的所有无系都放在右侧。

在其他情况下,如果你在图表布局中关心哪些在API端,
哪些在SPI (服务供应商)端,那么你可能必须明确声明这一点。

6.3.8 案例研究:用活图表呈现业务概览 136

6.3.9 示例:系统上下文图 142

6.3.10 自动生成设计文档所面临的挑战 145

6.4 小结 146

第7章 运行时文档 147

7.1 示例:活服务图表 147

7.1.1 在运行时中增强代码 148

7.1.2 发现架构 149

7.1.3 让这项工作起作用的魔法 149

7.1.4 更进一步 149

7.1.5 可见工作方式:工作的软件即其自身文档 150

7.2 可见测试 150

7.2.1 特定领域的符号 150

7.2.2 生成自定义的领域特定图表,从而获得视觉反馈 152

7.3 示例:使用事件溯源时的可见测试 154

7.3.2 根据事件溯源场景生成的活图表 156

7.4 内省的工作方式:内存中的代码即知识来源 157

7.4.1 使用反射内省 158

7.4.2 不使用反射内省 159

7.5 小结 160

第8章 可重构文档 161

8.1 代码即文档 161

8.1.1 文本布局 162

8.1.2 编码约定 164

8.2 命名作为初的文档 165

在设计时,搜索正确的词是对时间的有效利用。

好名称不仅在你阅读时有用,在你搜索内容时也很有用。良好的命名可以确保所有名称都是可搜索的。可搜索性方面失败的一个命名例子就是Go语言,考虑到它起源于Google这家“搜索公司"”,这一点特别有趣。

8.2.1 组合方法:你需要为它们命名 166

8.2.2 惯用命名受上下文影响 166

8.2.3 依靠框架编码 166

8.3 类型驱动文档 167

8.3.1 从基本类型到类型 167

8.3.2 被记录的类型和集成的文档 168

8.3.3 类型和关联 168

8.3.4 类型优于注释 169

8.4 组合方法 171

8.5 连贯风格 172

8.5.1 使用内部DSL 172

8.5.2 实现连贯接口 173

8.5.3 连贯风格的测试 173

8.5.4 创建一种DSTL 174

8.5.5 何时不应使用连贯风格 175

8.6 案例研究:由注释引导的重构代码示例 175

8.7 集成的文档 176

8.7.1 类型层次结构 177

8.7.2 代码搜索 177

8.7.3 源自实际用法的语义 177

8.8 使用纯文本图表 178

8.8.1 示例:纯文本图表 178

8.8.2 图表即代码 181

8.9 小结 182

第9章 稳定文档 183

9.1 常青内容 183

9.1.1 需求比设计决策稳定 183

9.1.2 高层级目标往往很稳定 184

9.1.3 很多知识并没有看起来那么稳定 184

9.1.4 案例研究:README文件 184

9.2 关于常青文档的提示 187

9.2.1 避免将策略文档与策略实现文档混在一起 187

9.2.2 确保稳定性 188

9.2.3 使用持久的命名 189

9.2.4 沿着稳定轴组织工件 189

9.3 链接的知识 190

9.3.1 不稳定到稳定的依赖关系 190

9.3.2 断链检查器 191

9.3.3 链接注册表 191

9.3.4 加书签的搜索 192

9.4 稳定知识的类别 192

9.5 愿景声明 193

愿景就是当你完成工作后世界会变成的样子。

有了清晰的愿景,每个团队成员的努力就能真正汇聚在一起来实现愿景。

9.5.1 领域愿景声明 194

9.5.2 目标 195

9.5.3 影响地图 195

9.6 投资稳定知识 196

因此,请不要犹豫,花些时间和精力来学习稳定的知识吧。尤其是业务领域知识和软件架构
的基础知识是常青内容,特别值得学习。

9.6.1 领域浸入 197

9.6.2 调查墙 197

9.6.3 领域培训 197

9.6.4 “过我的生活”活动 198

9.6.5 影子用户 198

9.6.6 长期投资 198

9.7 小结 198

第10章 避免传统文档 199

注意
文档只是一种手段,不是目的,也不是产品。

10.1 关于正式文档的对话 200

沟通渠道丰富度越高,沟通效率越高。
无反馈:录像带 > 录音带 > 纸
有反馈:两人白板前沟通 > 两人电话沟通 > 两人电子邮件沟通

即人们在白板前一起工作和交谈是最有效的沟通方式,而纸上的交流则是最无效的沟通方式。

在大多数情况下,要实现有效的知识共享,最好是通过简单的交谈、提向和回答来完成,而
不是通过书面文档。

因此,所有参与者之间的对话优于书面文档。与所有书面工件不同,对话是交互性且快速的,
能传达情感,并且带宽很高。

10.1.1 Wiio沟通定律 201

10.1.2 三个解释规则 202

“三个解释规则”来检查你的理解:
如果我对接收到的内容没有想出至少三种解释,那么我可能还没完全明白它的意思。
这条规则并不是说你其中的一个解释就是正确的解释, 但是它可以帮助你避免一种错觉,即
随机出现的第个解释就是正确的解释。

10.1.3 对话的障碍 202

来自不同团队或部门的人,或者被分配到不同项目或在不同地点的人,他们之间的对话往往比在同一团队或同一项目中的人少得多。他们倾向于使用更冷的(非交互式)而且效果更差的沟通方式,例如电子邮件或电话,而不是面对面的沟通。请务必注意,层级距离(即由不同的人管辖)与地理距离在阻碍对话方面的效果几乎一样。

10.2 协同工作,实现持续的知识共享 202

10.2.1 结对编程 203

结对编程时,写代码的人(称为驾驶员)为观察者讲述正在发生的事情,观察者反过来给予确认、备注、更正和任何其他类型的反馈。观察者(也称为导航员)与驾驶员交谈来指导正在进行的工作,建议可能的后续步骤,并提供解决任务的策略。

10.2.2 交叉编程 204

10.2.3 Mob 编程 204

Mob编程是一种软件开发方法,即整个团队在同一时间、同一空间、同一台计算机上做同一件事情。它有点像结对编程,即两个人同时坐在同一台计算机前在同一段代码上进行协作。通过Mob编程,团队里所有人都参与了协作,同时使用一台计算机来编写代码并将其输入到代码库中。

10.2.4 三个(或更多)好朋友 204

10.2.5 事件风暴即熟悉产品的过程 205

10.2.6 知识转移会议 205

10.2.7 持续文档 205

10.2.8 卡车系数 206

10.3 在咖啡机旁沟通 206

10.4 想法沉淀 208

10.5 一次性文档 210

10.6 按需文档 210

10.6.1 即时文档 210

Peter Hilton还有另一个编写文档的绝妙技巧, 他称之为“反向即时文档":
你可以通过在聊天室中提问(然后将答案粘贴到文档中)来诱使其他人编写即时文档,而不是预先编写文档。

10.6.2 尽早激发即时学习 212

10.6.3 惊讶报告 212

10.6.4 包括一些前期文档 212

10.7 互动式文档 214

10.8 声明式自动化 215

10.8.1 声明式风格 216

10.8.2 声明式依赖关系管理 216

10.8.3 声明式配置管理 218

10.8.4 声明式自动化部署 220

向导应该设计一些有用的异常,在问题发生时能准确地告诉你做什么、如何做、在哪里能解决这个问题。

10.8.5 机器文档 223

10.8.6 关于普遍自动化的评论 223

10.9 强制性规范 223

因此,使用一种机制来执行已成为规范的决策。使用工具检测违规行为并在违规时以可视化的警报形式提供即时反馈。不要浪费时间写没有人阅读的规范文档,而应该使强制执行的机制具有足够的自我描述性,以便可以将其用作规范的参考文档。

10.9.1 规则的一些例子 224

10.9.2 不断发展规范 225

10.9.3 强制或鼓励 226

像Sonar这种工具会提供不同规范集之间的继承(称为质量配置文件),以帮助实现这一目标。

10.9.4 声明式规范 226

10.9.5 工具的问题 227

10.9.6 规范还是设计文档呢 227

10.9.7 如果被篡改,保证标签无效 228

10.9.8 信任至上的文化 229

10.10 受限行为 229

10.10.1 轻松地做正确的事 229

10.10.2 不可能出错:防错API 231

10.11 避免编写文档的设计原则 231

10.11.1 可替换性优先 231

10.11.2 一致性优先 231

10.12 示例:零文档游戏 232

10.13 小结 233

第11章 超越文档:活设计 234

11.1 倾听文档 234

11.1.1 领域语言怎么了 235

11.1.2 通过巧合设计编程 235

11.2 谨慎决策 236

而“越简单”实际上意味着可以用更少但更有效的决策解决更多问题。

  • 对称:相同的代码或接口可以处理所有对称情况。
  • 更高层级的概念:相同的代码可以同时处理许多特殊情况。
  • 一致性:有些决策在各处重复,无一例外。
  • 可替换性和封装:边界内的局部决策无关紧要,因为即使关于这些决策的知识已经丢失了,稍后也可以重新考虑或重做。

11.2.1 “谨慎决策”并不意味着“预先决策” 238

11.2.2 文档是一种代码审查方式 239

11.3 丢脸的文档 239

11.3.1 示例:丢脸的文档 240

11.3.2 故障排除指南 240

11.3.3 丢脸的代码文档 241

11.3.4 记录错误还是避免错误 242

11.4 文档驱动开发 242

11.4.1 文档让你诚实 243

11.4.2 文档驱动和“避免文档”之间的明显矛盾 243

11.5 滥用活文档(反模式) 244

11.6 活文档拖延症 245

11.7 可降解的文档 245

11.8 干净透明 246

还可以通过使用bag命令(即Guava的多集)自己计算标记的出现次数:

1 bag. add(token)

你可以使用d3.layout.cloud.js库在HTML页面中渲染文字云,将单词数据转储到页面中。

11.8.1 诊断工具 248

11.8.2 使用正压清洁内部 250

11.9 无处不在的设计技巧 251

11.10 记者Porter采访Living Doc Doc先生 251

11.11 小结 253

第12章 活架构文档 254

12.1 记录问题 255

12.2 明确的质量属性 257

12.2.1 利害驱动的架构文档 257

12.2.2 显式假设 258

12.2.3 架构简洁说明架构质量高 258

12.2.4 持续发展:易于更改的文档 259

12.3 决策日志 259

因此,要针对最重要的架构决策维护-份决策日志。它可以像代码存储库根目录文件夹中的结构化文本文件一样简单。使决策日志的版本与代码库保持一致。 对于每个重要的决策,记录决策及其依据(为什么做出这个决策)、考虑的主要替代方案以及主要结果(如果有的话)。切勿更新决策日志中的条目,而是添加一个新条目来代替前一个条目,并提供对它的引用。

12.3.1 结构化决策日志的示例 260

12.3.2 用期刊或博客作为脑转储 263

12.4 分形架构文档 263

12.5 架构全景图 264

12.6 架构规范 266

在向人们描述一个解决方案时,最重要的部分是分享得出该解决方案的思考和推理过程。

12.7 透明的架构 268

12.7.1 架构注解 269

12.7.2 强制性设计决策 271

使用SonarQube内置架构约束模板或专门的架构声明库 (例如ArchUnit ),可以创建以下规则。

  • “持久层不能依赖于Web代码":禁止从**.dao中的类访问.web
  • “六边形架构”:禁止从.domain.访问. infra
  • “值对象不应将服务作为成员字段注入"

12.8 架构实现检查 272

12.9 测试驱动架构 272

你可以尝试在架构规模上遵循相同的过程。你所面临的挑战是所有事情的规模都变得更大,馈路也变得更长,这意味着当你最终获得反馈时,可能已经忘了你之前想要的是什么。

12.9.1 质量属性即场景 273

12.9.2 生产环境中运行时的质量属性 274

12.9.3 其他质量属性 274

12.9.4 从零散的知识到可用的文档 274

12.10 小规模模拟即活架构文档 275

12.10.1 小规模模拟的理想特征 276

小规模模拟必须具有以下特征。

  • 它必须小到能被普通人或开发人员理解:这是最重要的属性,它暗示了模拟不会涵盖原始系统的所有内容。
  • 你必须能修改它,而它必须能吸引人进行交互式探索:在不重构完整的模拟的情况下,仅仅通过用某个类或函数执行某些操作,代码应该能轻易地部分运行。
  • 它必须是可执行的,以便在运行时显示出动态行为:模拟必须通过执行预测结果,而且即使在计算过程中(如果可能的话),你也必须能轻松地观察这个运行过程,甚至可以在调试模式下使用跟踪或仅通过单独运行它的阶段来进行观察。

12.10.2 简化系统的技术 276

12.10.3 构建小规模模拟就有了一半的乐趣 277

12.11 系统隐喻 278

隐喻是利用大多数人已经熟悉的事物来发挥作用,因此用它解释新事物更有效。

12.11.1 通过谈论另一个系统来解释这个系统 278

12.11.2 即使没有先验知识也很有用 278

12.11.3 隐喻套隐喻 278

12.12 小结 279

第 13章 在新环境中引入活文档 280

13.1 秘密实验 280

13.2 新事物必须能用而且必须被接受 281

13.2.1 渐渐地开始 281

13.2.2 扩大活文档项目的范围并让人看到 282

13.3 案例研究:向团队成员介绍活文档的故事 283

13.3.1 对话优先 283

13.3.2 第 一次汇报 284

13.3.3 是时候讨论代码了 284

13.3.4 决策日志和导览 285

13.4 针对活文档的普遍反对意见 286

13.4.1 注解并不是用来编写文档的 286

13.4.2 “我们已经在做了” 286

13.5 将遗留文档迁移到活文档中 287

13.6 边际文档 287

13.7 案例研究:在批处理系统中引入活文档 288

13.7.1 README文件和现成的文档 288

13.7.2 业务行为 289

13.7.3 显露式运行和单一信息源 289

13.7.4 供开发人员使用的集成文档和供其他干系人使用的活词汇表 289

13.7.5 展示设计意图的活图表 290

13.7.6 联系信息和导览 290

13.7.7 微服务总图 290

13.8 向管理层推销活文档 291

13.8.1 从实际问题出发 291

13.8.2 活文档计划 292

13.8.3 对比当前的状况与承诺的更美好的世界——实现人们的愿望 293

13.9 在精神实质上合规 295

13.9.1 案例研究:遵守ITIL合规性要求 296

13.9.2 ITIL示例 296

13.10 小结 297

第 14章 为遗留应用程序编写文档 298

14.1 文档破产 298

14.2 遗留应用程序就是知识化石 298

14.3 气泡上下文 300

14.4 叠加结构 302

14.5 突出结构 303

14.6 外部注解 305

14.7 可降解的转化 305

14.7.1 示例:绞杀者应用程序 305

14.7.2 示例:破产 306

14.8 商定标语 306

14.9 强制执行的遗留规则 307

14.10 小结 308

补充知识:显而易见的文档(图灵社区下载)

活文档模式图表(图灵社区下载)

posted @ 2025-06-18 09:58  liqinglucky  阅读(32)  评论(0)    收藏  举报