You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
9.8 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 03 | DoD的价值你完成了工作为什么他们还不满意
你好,我是郑晔。
在开始今天的讨论之前,我们先来看一个小故事。小李是一个程序员,有一天,项目经理老张来到他身边,和他商量一个功能特性的进度:
> 老张:这有一个任务需要完成,你看一下。
> 小李:这个不难,两天就能做完,两天以后就能上线。
两天以后,老张又来到小李的身边验收工作:
> 老张:怎么样,做完了吗?今天能上线吗?
> 小李:我的代码写完了。
> 老张:测试人员测过了吗?
> 小李:还没有。
> 老张:那今天能测完吗?
> 小李:那我就不知道了。
> 老张:什么?我可是答应了业务的人,今天一定要上线的!
很明显,老张有些愤怒,而小李也有些委屈。于是,老张、小李和测试人员一起度过了一个不眠之夜。
听完这个故事,你有什么感想呢?先不急,我们继续看后面的故事。
又过了几天,老张又来找小李,给小李安排一个很简单的功能。在小李看来,一天就能搞定,而按照老张给出的时间表,小李有两天时间处理这个功能。小李心中暗喜:看来我可以“偷得浮生一日闲”了。
两天以后,老张又来检查工作。
> 老张:这个功能开发完了吗?
> 小李:写完了,你看我给你演示一下。
小李熟练地演示了这个新写好的功能,这次老张很满意:
> 老张:做得不错。单元测试都写了吧?
> 小李:啊?还要写单元测试吗?
> 老张:要不为啥给你两天的时间?
怎么会这样?小李心里很委屈,自己明明已经很好地完成了工作,老张是不是故意在找自己的麻烦呢?
好,故事讲完了。是不是有些似曾相识的感觉呢?为什么小李辛辛苦苦地工作,老张却总能挑出毛病来呢?老张是不是来挑刺的呢?其实,老张才没那么闲,小李的委屈主要是因为他和老张对于“完成”有着不一样的理解。换句话说,他们之间存在一个理解的鸿沟。
## 理解的鸿沟
在这个模块里,我们讨论的主题是“以终为始”。那我们第一个问题就是,“终”到底是什么?在前面这个例子里,“终”就是“完成”,可是,小李认为他的活已经做完了,老张却认为他没做完。
怎么会这样?二人之所以有分歧,归根结底,就在于二人对“完成”的定义理解的不同。
在第一个故事里,作为项目经理,老张认为“完成”应该是“上线运行”,而程序员小李则认为“完成”是“功能代码编写完毕”。这中间存在的理解偏差,包括了测试人员的测试工作,可能还包括了运维人员的上线工作。
在第二个故事里,老张给了小李两天时间。小李认为这两天都是编写功能代码的,而老张想的是,小李应该自己写好功能代码和单元测试,可能还包括了功能测试,这中间的差异是测试代码的工作量。
因为双方的理解不一致,所以无论怎样努力,小李都不可能达成项目经理老张的要求,正所谓“南辕北辙”。
那该怎么办呢?小李会说,我又不是老张肚子里的蛔虫,怎么才能和他达成一致呢?答案很简单,既然双方的理解有差异,那就把这个差异弥合上,后面的问题便也不是问题了。
弥合差异的方式有很多,有一个最佳实践,它的名字叫 DoDDefinition of Done完成的定义从这个概念的名字便不难看出它就是为了解决软件开发中常见的“完成”问题而生的。
## 完成的定义
DoD 这个概念本身并不复杂,它就是告诉我们怎样算是完成了,尽量减少因为理解偏差造成的各种浪费。具体怎么做呢?就是团队在开始工作前,先制定 DoD。以前面的场景为例团队可以规定
> 特性开发完成,表示开发人员经过了需求澄清、功能设计、编写代码、单元测试,通过了测试人员的验收,确保代码处于一个可部署的状态,相关文档已经编写完毕。
> 开发完成,表示开发人员编写好功能代码,编写好单元测试代码,编写好集成测试代码,测试可以通过,代码通过了代码风格检查、测试覆盖率检查。
大家都是聪明人,一旦 DoD 确定好了,谁该做什么事就一目了然了。这个时候,如果小李说“我已经开发完了”,却只是写好了功能代码,那就别怪老张手下无情了。
好了,你已经知道 DoD 是什么了,它简单到让人一目了然,相信你很快就能知道该怎样把它用到你的工作里。不过,我们不仅要知道怎么用,还要知道怎样让 DoD 更好地发挥作用。
* **DoD 是一个清单,清单是由一个个的检查项组成的,用来检查我们的工作完成情况。**DoD 的检查项,就是我们开发产品所需的一系列有价值的活动。比如:编写代码、编写测试代码、通过测试人员验收等。什么样的活动是有价值的,也许每个团队的认识是不同的。但如果你的团队认为除了功能代码,其他都没价值,也许这是个信号,说明你的团队整体上是缺乏职业素养的,在这样的团队工作,前景并不乐观。
* **DoD 的检查项应该是实际可检查的。**你说代码写好了,代码在哪里;你说测试覆盖率达标了,怎么看到;你说你功能做好了,演示一下。
* **DoD 是团队成员间彼此汇报的一种机制。**别把“汇报”想复杂了,最简单的汇报就是说一句“这个功能做完了”。**当我们有了 DoD做事只有两种状态即“做完”和“没做完”。**在团队协作中我们经常会听到有人说“这个事做完了80%”对不起那叫没做完根本没有80%做完的说法。
在前面的讨论中,我们所说的 DoD 只是从个人层面入手。在团队层面,我们也可以定义 DoD。
* 某个功能的 DoD比如这个功能特性已经开发完成经过产品负责人的验收处于一个可部署的状态。
* 一个迭代的 DoD比如这个迭代规划的所有功能已经完成。
* 一次发布的 DoD比如整个软件处于可发布的状态上线计划已经明确。
## 站在 DoD 的肩膀上
至此,我们只是从软件开发团队内部协作的角度来谈 DoD。但实际上**它不仅局限在团队内部协作上,如果你可以放开思路,会发现 DoD 的思维在工作中用途非常广泛。**比如,当我们需要和其他团队合作开发一个接口时,我们都知道第一步就是要把接口定义下来。
那么,怎样才算定义完成?很多团队认为落在字面上就够了。但是有了 DoD 的思维,我们定义接口,就会去明确定义可检查的检查项。那么在定义接口这件事上,什么才是“可检查”的呢?我们可以参照一个可运行的接口来进行评估。只要检查:
* 服务方提供的接口是不是和这个可运行的接口返回值是一样的;
* 调用方是否可以和这个可运行的接口配合使用。
谁错了,谁改去。你可能会问,应该参照哪些可运行的接口呢?这不难解决,现在模拟服务器的框架到处都是。如果你不介意的话,我的 [Moco](http://github.com/dreamhead/moco) 就是这样一个开源项目,你可以看一下。
在协作中一旦确立好 DoD我们甚至可以通过流程把它固化下来从而更高效高质地完成工作。当然我们在工作生活中难免会有一些临时的工作它们没有复杂到需要一个流程但是也可以用 DoD 思维来高效地解决。比如:
> 经常会有人过来,让我帮忙做些事。运用 DoD 的思维,我首先会问他我具体要做哪些事,确认好细节(相当于定义好“检查项”),然后我就知道,这个忙我能帮到什么程度。
> 我请别人帮忙的时候,也会很清楚告诉他,哪些事是需要他做的,尽量减少不必要的误解。
**DoD 是一个思维模式,是一种尽可能消除不确定性,达成共识的方式。**我们本着“以终为始”的方式做事情DoD 让我们能够在一开始就把“终”清晰地定义出来。
人与人协作中经常会出现各种问题根本原因就是有太多因为理解差异造成的误解进而浪费了大量的时间而DoD 就是一种将容易产生歧义的理念落到实处的方法。
## 总结时刻
好,我们来总结一下今天学到的内容。首先,你应该知道,人与人协作,总会有这样或那样的理解差异。开始协作之前,我们最好先同步一下彼此的理解,确保之后不会因为理解不一致,而让协作方措手不及。
怎样解决大家的理解偏差呢,我介绍了 DoD完成的定义它是行业中的一种最佳实践能够在团队内部很好地同步大家对“完成”的理解。好的 DoD 是一个可以检查的清单,可以确保你不遗漏任何事情。
如果深入领会 DoD你会发现 DoD 可以灵活应用在不同的协作场景中。比如应用于个人工作、团队工作,甚至跨团队工作。当然,你也可以将它灵活地运用于各种生活场景,弥合人与人理解之间的差异,更好地协作与沟通。
如果今天的内容你只能记住一件事,那请记住:**在做任何事之前,先定义完成的标准。**
最后,我想请你回想一下,你在工作或生活中,是否发生过因为双方理解差异导致的问题或不快呢?有了 DoD 的概念以后,你是不是有了一些新的想法呢?欢迎在留言区留言。
感谢阅读,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给你的朋友。