gitbook/10x程序员工作法/docs/81515.md
2022-09-03 22:05:03 +08:00

128 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 答疑解惑 | 如何分解一个你不了解的技术任务?
你好,我是郑晔。
在“任务分解”这个模块,我以测试为核心,讲解了任务分解这个原则,同时也给你介绍了一些最佳实践,帮助你更好地理解任务分解的重要性,以及应该怎样分解任务。
同学们对任务分解这个原则大多是表示认同的,但就一些具体应用的场景,还是提出了自己的问题。
在今天的答疑中,我选择了几个非常典型的问题来进行深入讨论。
## 问题1面对不了解的技术我该如何分解任务
pyhhou 同学提到
> 很想听听老师的意见,就是在一个自己不熟悉的,充满未知的项目中该怎么更好地进行任务分解?
> [——《11 | 向埃隆·马斯克学习任务分解》](http://time.geekbang.org/column/article/77913)
shniu 同学提到
> 想请问一下老师,面对探索型的需求,调研型的需求如何做任务分解呢?
> [——《15 | 一起练习:手把手带你分解任务》](http://time.geekbang.org/column/article/78542)
这是一个很好的问题。在这个模块讨论开发中的任务分解时我说的都是确定了解的某项技术比如数据库、REST 服务等等,因为这是开发中最常见的场景,也是最基础的能力,连熟悉的技术都做不好分解,就别说不熟悉的技术了。
那如果不了解这项技术呢?**答案很简单,先把它变成你熟悉的技术。**一旦变成了你熟悉的技术,你就可以应用在这个模块中学到的,面对确定性技术的分解方案。
我知道,这个答案你并不满意。其实,你真正的问题是,怎么把它变成你熟悉的技术。
我的答案是,**做一次技术 Spike。**这里之所以用英文是因为我没有找到一个特别合适的词来翻译。Spike 这个词的原意是轻轻地刺,有人把它翻译成调研,我觉得是有些重了。
Spike 强调的重点在于快速地试,和调研的意思不太一样。既然是快速地试,就要在一定的时间内完成,比如,五人天,也就是一个人一周的时间,再多就不叫 Spike 了。一些简单的技术,用一天时间做 Spike 就差不多了。
这里强调的重点在于,要做一次技术 Spike。**Spike 的作用就在于消除不确定性,让项目经理知道这里要用到一项全团队没有人懂的技术,需要花时间弄清楚。**
项目经理比你更担心不确定性,你清楚地把问题呈现在他面前,项目经理是可以理解的,他更害怕的是,做到一半你突然告诉他,项目进度要延期。
把事情做在前面,尽早暴露问题,正是我们要在下一个模块要讨论的一个主题。
好,那么接下来的问题变成了:怎么做技术 Spike 呢?
这里,我假设你已经通过各种渠道,无论是新闻网站,还是技术 blog又或是上级的安排对要用的技术有了一些感性的认识至少你已经知道这项技术是干什么的了。
接下来,我们要进入到技术 Spike 的任务分解。
首先,快速地完成教程上的例子。稍微像样点的技术都会有一个教程,跟着教程走一遍,最多也就是半天的时间。之所以要快速地完成教程上的例子,是为了让你有一个直观的认识,这时候,你对这项技术的认识就会超过新闻网站的报道。
其次,我们要确定两件事:**这项技术在项目中应用场景和我们的关注点。**
技术最终是要应用到项目中的,本着“以终为始”的原则,我们就应该奔着结果做,整个的 Spike 都应该围绕着最终的目标做。
很多程序员见到新技术都容易很兴奋,会把所有的文档通读一遍。如果是技术学习,这种做法无可厚非,但我们的目标是做 Spike快速地试没有那么多时间必须一切围绕结果来。
项目中的场景有无数,我们需要选择最重要的一个场景,而针对着这项最重要的场景,我们还要从这项技术无数功能中选取最需要的几个,而不是“满天撒网”。
再有是我们要找准关注点,比如,采用新的缓存中间件是为了提高性能,那关注点就是性能,采用新的消息队列是为了提升吞吐,那关注点就是吞吐。我们选用一项新技术总是有自己的一些假设,但这些假设真的成立吗?这是我们需要验证的。
无论是场景,还是关注点,我们要在前面先想清楚,其目的就是为了防止发散。当时间有限时,我们只能做最重要的事,这也是我在专栏中不断强调的。
确定好场景和关注点,接下来,我们要开发出一个验证我们想法的原型了。这个原型主要目的就是快速地验证我们对这项技术的理解是否能够满足我们的假设。开发一个只有主线能力的原型,对大部分程序员来说并不难,这里就不赘述了。
当你把想法全部验证完毕,这项技术就已经由一项不熟悉的技术变成了熟悉的技术。我们前面的问题也就迎刃而解了。这时候,你就可以决定,对于这项技术,是采纳还是放弃了。
但是,我这里还有一点要提醒,当你确定要使用这项技术时,**请丢弃掉你的原型代码。**
你或许会说,我辛辛苦苦写了几天的代码就这么丢了?是的,因为它是原型,你需要为你的项目重新设计。
如果顺着原型接着做,你可能不会去设计,代码中会存在着大量对这项技术直接依赖的代码,这是值得警惕的,所有第三方技术都是值得隔离的。这是我们会在“自动化”模块讨论的内容。
## 问题2项目时间紧该怎么办
在这个模块里,我花了大量的篇幅在讲测试,很多同学虽然认同测试的价值,却提出了开发中普遍存在的一些情况。
玄源 同学提到
> 很多时候项目时间很紧经常会提测后再补测试或者直接code review测试就不写了。
> [——《12 | 测试也是程序员的事吗?》](http://time.geekbang.org/column/article/77917)
这是一个非常典型的问题,我在之前做咨询的时候,经常会遇到很多团队说,项目时间紧,所以,他们没有时间做测试。
这里面有一个非常经典误区:**混淆了目标与现状。**目标是应该怎么做,现状是我们正在怎么做。我们都知道现状是什么样的,问题是,你对现状满意吗?如果每个人都对现状是满意的,就不会有人探索更好的做法。
**假设现在不忙了,你知道该怎么改进吗?**
遗憾的是,很多人根本回答不了这个问题,因为忙是一种借口,一种不去思考改进的借口。
我之所以要开这个专栏,就是为了与大家探讨行业中一些好的做法。
回到这个具体问题上,我们在专栏开始就在讲以终为始,首先要有一个目标,专栏中介绍的各种实践都可以成为你设置目标的参考。有了这个目标再来考虑,如何结合我们工作的现状来谈改进。
接下来我们以测试为例讨论一下具体的改进过程。用我们专栏最初讲过的思考框架看一下假如我们的现状是团队之前没什么自动化测试而我们的目标是业务代码100%测试覆盖。如果要达成这个目标,我们需要做一个任务分解。
这时你会发现,分解的过程主要需要解决两方面的问题,一个是与人的沟通,另一方面是自动化的过程。
与人的沟通,就是要与团队达成共识。关于这点,你可以尝试将专栏里讲到的各种最佳实践以及其背后的逻辑,与团队进行沟通,也可以把专栏文章分享给他们。
再来,我们考虑一下自动化的改进,因为我们的现状是没什么测试,所以,不能强求一步到位,只能逐步改进。下面我给出了一个具体的改进过程:
* 把测试覆盖率检查加入到工程里,得到现有的测试覆盖率。
* 将测试覆盖率加入持续集成,设定当前测试覆盖率为初始值。测试覆盖率不达标,不许提交代码。
* 每周将测试覆盖率调高比如5%或10%直到测试覆盖率达到100%。
这样,我们就找到了一条由现状通往目标的路径,接下来,就是一步一步地具体实施了,由团队成员逐步为已有代码补充测试。
## 问题3多个功能同时开发怎么办
妮可 同学提到
> 公司经常存在有两个需求同时开发的情况。请问老师所在的团队如何解决单分支上线不同步的情况呢?
> [——《14 | 大师级程序员的工作秘笈》](http://time.geekbang.org/column/article/78507)
在主分支开发模型中有一些常见的解决多功能并行开发的方法其中Feature Toggle 是最常用的一个,也就是通过开关,决定哪个功能是对外可用的。
关于这一点Y024 同学也补充了一些信息。
> Feature toggle功能开关分享两篇文章
> [1\. Feature Toggles (aka Feature Flags)](http://martinfowler.com/articles/feature-toggles.html)
> [2.使用功能开关更好地实现持续部署](http://www.infoq.cn/article/function-switch-realize-better-continuous-implementations)
不过如果用户故事划分得当你可以很快完成一个完整的业务需求。实际上Feature Toggle 只是一个非常临时的存在。但如果你在一个遗留系统上工作一个功能要跨越很长的周期Feature Toggle 才显得很有用。
额外补充一个与主分支开发模型相关的常用技术,如果你想对遗留系统做改造,传统的做法是,拉出一个分支。
如果在一个分支上怎么做呢?可以考虑采用 [Branch by Abstraction](http://www.martinfowler.com/bliki/BranchByAbstraction.html),简言之,再动手改造之前,先提取出来一个抽象,把原先的实现变成这个抽象的一个实现,然后,改造的过程就是提供这个抽象的一个新实现。这种做法对设计能力有一定要求,所以,对很多团队来说,这是一个挑战。
好,今天的答疑就到这里,请你回想一下,你在工作中是否也遇到过类似的问题呢?你又是怎么解决的呢?欢迎大家在留言区写下你的想法。
感谢阅读,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给你的朋友。