共享语言

36 min read

这篇文章想聊聊与其他职能的沟通。

做开发时,我花在弄清楚该做什么上的时间,和写代码的时间一样多。与产品经理来回确认需求,与设计师对齐界面,向懂领域的人询问某个术语究竟指什么。而这个过程一旦错位,代价远大于把代码写错的代价,这一点我已经经历过好几次。

最近我读了 James Samuel 写的工程领导者的日常工作。作者把领导者的工作分成六项,最先讨论的就是信息收集。理由是所有的决策、方向和行动,都依赖于对当下正在发生什么的准确理解。

我确实希望将来能担任领导角色,但读到这一段之后浮现的想法有些不同。**如果领导者最先处理的工作是信息收集,那么对一线执行者而言,与之对应的就是需求的梳理。**我现在处理需求的方式,日后就会成为我处理组织信息的方式。

这篇文章并不想谈领导力。它谈的是我作为一线执行者与其他职能沟通时,究竟做错了什么,又能把什么当作工具。先说结论:我逐渐认为这不只是态度问题。有一个可以替代的说法叫 ubiquitous language,我们来看看它是什么。

同一个词,不同的含义

Martin Fowler 在Bounded Context一文中举了电力公司的例子。我遇到的错位,相当一部分正是这种形态。

在这里,“meter”这个词在组织的不同部分含义有微妙差别:它指的是电网与某个地点的连接,还是电网与某位客户的连接,抑或是物理电表本身?

here the word 'meter' meant subtly different things to different parts of the organization: was it the connection between the grid and a location, the grid and a customer, the physical meter itself

同一个“meter”,在组织的不同部门里指的是微妙不同的东西。Fowler 还补充说,这种混乱并非那个案例的偶然。他说自己反复见到 Customer、Product 这类多义词引发同样的混乱。

**这并不是因为与会者不擅长开会。**只要组织内部存在不同的语境,同一个词分化就是自然的事;放任不管,最终连代码也会跟着分化。

这个话题的技术背景,我在领域模型里讨论过一次。那时谈的是如何在代码中表达模型。而本文要谈的是那个模型形成之前,人与人之间对话的阶段。

有两种含义的词

那么,这种事为什么会结构性地反复出现呢?有两条解释路径。

一条来自组织结构。Mel Conway 于 1968 年发表在 Datamation 上的论文How Do Committees Invent?指出,组织无法灵活改变自身沟通结构的程度有多深,它就会把自己的形象刻印到所产出的一切设计物上。通常被引用为康威定律的那一句话,其实是作者日后自己整理出的表述,而我觉得 1968 年原文中的这段描述更为直接。

我从这句话里读出的实务含义,是“刻印”这个说法。因为它意味着术语的分化不会止于对话,而是原封不动地留在产出物里。前面的“meter”就是如此。如果各方对“meter”的范围理解不同却各自动手去做,这个差异不会留在会议纪要里,而会留在表名、API 响应字段和界面文案里。而从那一刻起,修改的成本就与再谈一次的成本不可同日而语了。

一线执行者能做的和不能做的,在这里分开。改变组织的沟通结构超出了执行者的能力范围。但让术语的边界变得可见,是当下就能做的事。也就是写清楚本文档中某个词的含义范围,若与其他团队使用的词不同,就明确指出不同。后面要看的工具,全都是让这件事变容易的装置。

另一条则更为根本。从认知科学的角度看,协作本来就只能建立在共享的背景之上。Herbert Clark 与 Susan Brennan 于 1991 年撰写的Grounding in Communication以钢琴二重奏开篇。两位演奏者若不预设大量的共享信息,也就是 common ground,甚至无法开始对齐内容。这里的 common ground 指的是相互知识、相互信念与相互假设。作者还明确指出,一切集体行动都建立在 common ground 及其累积之上。

把这两条并排看过之后,我得到的视角是这样的。**术语出现偏差不是事故,而是默认状态。**对齐的状态反而是需要付出维护成本的例外。那么由谁、以什么方式支付这份成本,就成了实务上的问题。

developer 的职责不是听写

对此,我找到的最明确的答案来自 Eric Evans。

Evans 在 2003 年出版的 Domain-Driven Design 中提出了 ubiquitous language 这一模式。它常被简化为“让 developer 和领域专家使用相同的术语”,但读原书会发现处方要具体得多。他要求团队把模型作为语言的骨架,并约定在团队内的一切沟通和代码中坚持使用这套语言。而紧随其后的那句话,对我而言最为重要。

领域专家会对那些别扭或不足以传达领域理解的术语与结构提出异议,而 developer 则留意那些会让设计栽跟头的歧义或不一致。

Domain experts object to terms or structures that are awkward or inadequate to convey domain understanding, while developers watch for ambiguity or inconsistency that will trip up design.

领域专家对不足以传达领域理解的别扭术语与结构提出异议,而 developer 则监视那些会推倒设计的歧义或不一致

读到这句话后,我修正了对自身角色的理解。在此之前,我在需求会议上把自己视为接收者。我以为产品那边定下来之后,准确接收并实现就是我的工作。可 Evans 界定的 developer 职责并不是接收。**而是发现歧义并把它交还回去。**这不是消极配合,而是积极监视。

(顺带一提,Fowler 在自己的文章中把这句话写成了“Domain experts should object ... developers should watch”。原书里并没有情态动词。差别虽小,但原书读起来更为断然。那语气不是说这样做比较好,而是说这样做就是这个模式的定义。)

那么歧义该怎么发现呢?Evans 对此也给了答案:在对话中反复使用,术语理解上的差异就会显现。我是这样读这句话的。歧义不是靠精读文档找出来的。无论把需求文档读得多仔细,“会员”这个词指代三种东西的事实都不会浮现。只有把这个词放到实际案例上反复使用,它才会分化。像“已注销的人也算会员吗?”这样的问题冒出来的瞬间,就是那个分岔点。

可是这样的对话为什么总是谈不拢

到这里都还是处方。问题在于,我曾经有一段时期明知这个处方却做不到。为什么我没有反复去问呢?

让我们再回到 Clark 与 Brennan 的论文。作者把“将说出口的内容变成 common ground 的一部分”这一过程命名为 grounding。并针对人们在这个过程中的行为提出了一条原理:最小协作努力原理(the principle of least collaborative effort)。这条原理源自一个观察,即人不喜欢比必要程度更卖力地工作。

关键的段落在这里。

根据最小协作努力原理,人们应当以所需的最少共同努力去完成 grounding。但什么事情耗费努力,会随沟通媒介发生剧烈变化。

By the principle of least collaborative effort, people should try to ground with as little combined effort as needed. But what takes effort changes dramatically with the communication medium.

**耗费努力的地方会随媒介发生剧烈变化。**在某种媒介中可用的确认手段,在另一种媒介中可能根本不可行,即便可行成本也高得多。作者尤其指出,在对方无法即时接收的媒介中,指望他人来纠正误解的成本会变得非常高,于是说话的人就会设法回避。

这里有一点要事先说明。这篇论文写于 1991 年,作者比较的媒介是面对面对话、电话、书信和电话答录机之类。**它并不涉及 Slack 或 Notion。**grounding 成本随媒介变化这个框架是作者的,而把它套用到今天的异步工作频道上,是我的解读。

这样套用之后,就能解释我为什么没有反复发问了。在以文本接收需求文档、又以文本确认的环境里,每遇到一处含糊就发一条确认消息,成本很高。你不知道答复什么时候来,还担心问了好几次会显得像是没听懂。于是人自然而然就滑向了自己的解读。

这里需要区分两股力量。一股是媒介抬高了确认成本,这是 Clark 与 Brennan 说的。另一股是担心问多了显得无能,这并非他们的原理所预测的,而属于后文心理安全感那一侧的话题。准确地说,最小协作努力原理预测的是会挑一种更便宜的确认方式,而不是不再确认。收起确认转向猜测,不是原理在起作用,而是 grounding 的失败。而那个解读错了的事实,要等到实现做完之后才会显露。

确认到什么程度才算够

那么每一处含糊都得去问吗?这不现实,我也没见过这么做的人。对于这个问题,论文同样给出了标准,就是 grounding criterion。它指的是双方彼此相信,听者已经在足以支撑当前目的的水平上理解了说话者的意思。作者在此之前还补了一句:完美的理解本来就不可能。

这个标准让我觉得实用的原因,是它把目标调低了。不需要完美地理解需求。**只要在足以支撑眼下要做的事的程度上彼此相信就够了。**作者还说,目的一旦改变,标准也必须随之改变。

这一点在实务中会成为调节确认力度的依据。在还在探索方向的场合,抓着“已注销的人也算会员吗”不放,对话就推进不下去。那个阶段需要的是关于要做什么、为什么做的共识,而不是边界值的确定。反过来,在进入实现之前,这个问题就必须提出来。此时双方必须能够相信彼此对“会员”的范围想的是同一件事,否则代码就会堆在错误的前提之上。

所以,即便遇到同样的含糊,**我也会根据当下处于哪个阶段而区别对待。**探索阶段就记在清单上先往前走,临近实现时再打开那份清单逐条关闭。推迟确认和放弃确认是两回事。

在这个环节,有一个很适合搭配使用的工具。Matthew Skelton 与 Manuel Pais 的 Team Topologies 把团队之间的互动分为三种模式:在约定的期间内共同发现新事物的 collaboration,一方提供、一方消费的 X-as-a-Service,以及一方帮助并辅导另一方的 facilitation。

它原本讲的是组织设计,但我觉得把它缩小到单场会议来用很实用。**如果双方对当下这场对话属于哪种模式的认知不一致,会议就会错位。**产品经理认为这是传达既定结论的场合,而 developer 认为这是共同发现的场合,那么 developer 的提问听起来就不像协作,而像抬杠。反过来也有。如果 developer 是来接收已确定的规格,而产品经理还在探索阶段,developer 就会因为拿不到规格而着急。

所以我最近会在会议开头先确认这一点:“这件事还是开放的,还是我们在确认已经定下来的内容?”这一个问题,就能改变之后整场对话的性质。这和把 grounding criterion 按目的做调整是同一回事。

分辨率对不上,对话就会空转

即便对齐了模式,仍有问题残留。我经常遇到的另一种错位,是双方在用不同的分辨率说话。

产品经理用文字给出的需求,大多太过抽象。像“让用户能方便地查看预约记录”这样的句子,看不出有几个界面,也看不出从哪里跳到哪里。反过来,设计师给的稿子又太过具体。连按钮颜色和留白都定好了,反倒难以讨论“这个流程对不对”。

Basecamp 的 Ryan Singer 所写的 Shape Up 精准地点出了这个问题:一上来就从线框图或具体的视觉布局入手,就会被不必要的细节困住,无法按需要的广度去探索。因此Shape Up 提出的方案是介于两者之间的表达。它被称为 breadboarding,概念借自电气工程。面包板是一种具备实机全部元件与接线、却没有工业设计的原型。所以要画的东西也正好三样:可以跳转到的位置(places)、用户可以操作的东西(affordances),以及展示该操作把用户带往何处的连接线(connection lines)。

需求分辨率的三个层级:文字、面包板、设计稿各自能回答的问题

我看好这个技法的原因,是它是 developer 做得出来的产出物。不必请产品经理写得更详细,也不必等设计师出稿,就可以当场把自己理解的流程画出来,反问一句“我是这么理解的,对吗”。这可以说是执行 Evans 所说的监视(把歧义交还回去)的具体方法。而从上一节的视角看,这是一个降低 grounding 成本的装置。一张图,抵得上用文字来回确认好几轮。

不过这个分辨率比想象中难以维持。画着流程,自然而然就会滑到“这里的按钮放右下角是不是更好”之类的讨论上。我自己也这样过几次。一旦这样滑下去,当场正在讨论的问题,也就是这个流程对不对,就悄悄消失了。流程尚未确定却在敲定按钮位置,等到之后流程一变,那些讨论就会被整块丢掉。

所以在这个阶段,我会刻意维持一张画得不好的图。如果只有方框、箭头和名称,对方也就不会想去挑细节,只会针对流程做出反应。图的完成度低,在这个工具里反而是一项功能。(要按住想画得漂亮的心思,比想象中难)

抽象层级这个概念本身可以成为协作工具,这一点与我在抽象化里谈过的内容相通。那时说的是代码的抽象层级,而对话里也有同样的东西。

把规则、示例和问题分开

对齐分辨率的另一种方法,是把讨论本身结构化。

由 Cucumber 项目负责人 Matt Wynne 在 2015 年介绍的Example Mapping就是如此。他把许多团队觉得需求讨论困难的原因,诊断为缺乏结构导致耗时又无聊。于是团队既不会定期做,也不会一致地做。我正是如此。需求会议一旦拖长,下次就想快点结束,而草草结束,含糊之处就原样留了下来。

Example Mapping 用四种颜色的卡片来划分讨论。黄色是当下讨论的 story,蓝色是规则或验收标准,绿色是说明该规则的具体示例,而红色是不知道答案的问题。

其中,**我认为红色卡片才是核心。**其余三种是整理技法,而红色卡片是把“不知道”变成会议正式产出物的装置。说出自己不知道,不再是拖慢会议的行为,而成了会议本该产出的结果。

这为什么重要,只要想想反面情形就很清楚。在没有红色卡片的会议上遇到含糊之处,选项只有两个:现在纠缠下去把会议拉长,或者先跳过之后自己一个人去解读。正如上一节所见,人大多会选后者。可只要多了一张卡片,就出现了第三个选项。**记下来往前走,同时不让它消失。**会议继续推进,而含糊之处并未被抹去,仍留在清单上。

绿色卡片也起着类似的作用。只写规则时大家都会点头,可一旦有人要写出说明该规则的具体示例,解读就会分开。这可以说是把 Evans 所说的“在对话中反复使用就会显现差异”搬进了会议形式。如果要求每条规则配三个示例,其中总有一个会冒出“咦?这种情况怎么算?”。(以我的经验,那个问题没有出现的会议,不是大家都理解了的会议,而是各自理解得不一样的会议)

类似思路下,BDD 圈子里长期使用的 Three Amigos 也是如此。它主张业务、开发与测试这三种视角各自抛出不同的问题,而Agile Alliance 术语表把这些问题整理为:想解决什么问题,要如何构建解决该问题的方案,以及这个怎么样、可能会发生什么。第三个问题始终不出现的会议会变成什么样,大概不必特意说明。

做一个写下未知的格子

可是,我们为什么难以打出红色卡片呢?说到这里,就绕不开心理安全感的话题。

Amy Edmondson 于 1999 年发表在 Administrative Science Quarterly 上的论文,是正式确立团队心理安全感这一概念的研究。(论文本身把 1965 年 Schein 与 Bennis 的研究列为源头)它把团队心理安全感定义为一种共享信念,即团队是一个可以承担人际风险的安全场所。说自己不知道、提出反对意见、承认失误,都属于此列。论文调查了一家制造业公司的 51 个团队,结果显示心理安全感与学习行为相关,而这种学习行为在心理安全感与团队绩效之间起中介作用。

不过,这篇论文里让我觉得最实用的句子并不是定义,而是紧随其后的那一句。

多数情况下,这种信念往往是隐性的:被视为理所当然,个人和整个团队都不会对它给予直接关注。

For the most part, this belief tends to be tacit—taken for granted and not given direct attention either by individuals or by the team as a whole.

也就是说,这种信念大多是隐性的,个人和团队都不会对它给予直接关注。

从这里开始是我的推测。论文说到的是这种信念是隐性的,至于“所以做个表格就好”这样的处方,论文里并没有。不过我见过好几次,隐性的东西不会因为宣告而改变。说一句“我们团队是可以问自己不懂的事情的团队”,往往改变不了什么。所以我认为上一节的红色卡片很重要。把“不知道”变成表格里的一个格子,填写它就从勇气变成了流程。

当然,反驳是成立的。在不安全的团队里,红色卡片的格子恐怕就是空着。这个指摘没错,我也无意主张这个工具能创造出安全感。只是,格子存在的话,至少**空着这件事会变得可见。**这就有了一个可以发问的位置:是因为没人有疑问才空着,还是因为难以开口才空着。

同样的想法也已经进入了实际的文档格式。看看 DDD 社区制作的Bounded Context Canvas,它是一个用于设计并记录单个上下文的协作工具,格子的构成很有意思。名称与目的、战略分类、领域角色、入站与出站沟通,然后是 Ubiquitous Language、业务决策、Assumptions、验证指标,以及 Open Questions

写共享语言的格子、写假设的格子、写开放问题的格子各自独立。画布的说明写道,书写目的这个行为本身就会迫使模糊的想法被清晰地表达出来,并把整个团队放到同一页上。

我认为这个思路是面对沟通问题最现实的路径。与其试图改变人的态度,不如**为那些难以说出口的事情做一个格子。**写Toss Frontend Fundamentals 模拟考重构复盘的时候我也有类似的感受:好的结构不是要求人做得好,而是让人容易做好。

这为什么不是偏好问题

读到这里,可能会有这样的反应:说得挺好,可归根结底不就是“好好沟通”吗?那不是性格问题吗?

我也曾这样想过一阵子。但这部分是有数据的。

DORA 在讨论组织文化时,引用了社会学家 Ron Westrum 的分类:权力导向的 pathological、规则导向的 bureaucratic,以及绩效导向的 generative。而DORA 的官方文档是这样总结自身研究结果的。

高信任并重视信息流动的组织文化,能够预测软件交付绩效。

organizational culture that is high-trust and emphasizes information flow is predictive of software delivery performance

高信任且重视信息流动的组织文化能够预测软件交付绩效。这说的不是沟通顺畅的团队心情好,而是它是一个与绩效同向变动的变量。

不过,这里的“预测”不能读作因果。DORA 的数据来自同一批受访者同时回答文化与绩效的问卷,是组织层面的相关性。对组织满意的人两边都给出宽松评分的可能性依然存在,而且从组织层面的关系,也无法直接推出个人该如何行动的处方。所以凭这份材料能说的仅止于此:信息流动并不只存在于偏好的领域,它处在一个与绩效同向变动的位置上。

同一份文档还整理了 Westrum 所说的好信息的三个性质:能回答接收者需要的问题、时机恰当,以及以接收者能有效使用的方式呈现。值得留意的是,三者的标准都落在接收者身上。共享得多,并不等于信息流动得好。

Google 的 Project Aristotle 也是常被引用的资料。根据re

上公开的内容,他们调查了 180 个团队,对数百个变量跑了 35 个以上的统计模型,提出影响团队效能的五个因素:心理安全感、可靠性、结构与清晰度、意义,以及影响力。而结论是,比起团队里有谁,这个团队如何协作更为重要。

不过有一点我想说明。官方页面写明这五个因素是按重要性排序的,并把心理安全感放在最前面。但引用这项研究的文章中常见的“压倒性第一”这类关于量级的表述,那个页面上并没有。存在顺序,和压倒其余,是两回事。所以本文不主张量级。若要论述心理安全感的重要性,依托上一节 Edmondson 的原论文才是准确的做法。

再回到领导者的话题

回到开头引用的那篇文章。

James Samuel 在最先讨论信息收集时说,一线执行者时期的方法会失效。作为个人贡献者时,你握有自己工作的全貌,可一旦背负起对人的责任,就无法再沿用过去的方法。因此他把过滤噪声、将信息综合成一幅连贯的现实图景的能力列为必需能力,因为没有哪个管理者能处理一切。

我觉得这与前面看到的 Westrum 关于好信息的三个性质是同一回事。重点不在于收集得多,而在于把它变成可用的形态。而这与我现在处理需求时所做的事并无二致。从需求文档的句子中挑出含糊之处,用 breadboard 重画一遍来确认,把不知道的事情留作红色卡片,这正是过滤噪声、构建连贯图景的练习。

作者关于决策留下的话也让我印象深刻:等待确定性本身也是一种决策,并且伴随着成本。等到需求完全明确为止,同样如此。所以,比起完美的理解,“足以支撑当前目的”这一 grounding criterion 才是实用的标准。

结语

总结一下。

与其他职能的沟通失败,大多不只是态度问题。只要组织内部存在不同的语境,同一个词分化就是默认状态,而对齐的状态反而是需要付出成本去维持的例外。支付这份成本的方式就是共享语言,而在其中,developer 的职责不是把需求听写下来,而是监视歧义并把它交还回去。

可是交还回去是要花力气的,而人总想把这份力气降到最低。所以我决定不依赖意志,而是使用三样东西:先确认这场对话属于哪种模式;用介于文字与设计稿之间的分辨率把流程画出来并交还回去;以及在会议的表格里预留一个写下未知的格子。这三样都不要求人改正态度,而是让正确的做法更容易做到。

我还不是领导者,写在这篇文章里的东西也没有在那个位置上验证过。团队规模或组织文化不同,总会有行不通的地方。不过有一点,我现在似乎可以确信。日后处理信息的方式不是重新学来的,而是当下处理需求的习惯原样长大的形态。所以我最近尽量不再像从前那样,羞于在会议上问一句“那是什么意思”。

如果读到这里的你,能想起最近某场会议上自己点了头、其实并不确定的某个词,那么我建议你下次把那个词再用一次。反复使用,它就会显现。

참고 자료

📚相关文章

评论