学到3点:
工程能力和技术能力同样重要,但被严重低估了。
TDD是最具效能的工程化开发方法。
掌握TDD并不容易。
程序员是掌握技术还是工程能力?
新技术的出现,经常会给我们带来焦虑。
程序员究竟是搞技术的,还是做工程的?这是我们在思考自身职业定位时,要首先去思考和回答的一个问题。
技术能力和工程能力是同等重要的,但工程能力却是我们长期忽略和欠缺的。
技术能力还是工程能力?
letcode刷题属于技术能力。
而项目里写CRUD,看似不起眼,更多是一项工程能力。
工程能力的第一步是,不要成为别人的绊脚石,成为项目的瓶颈。
我可以将工程能力总结为:在团队协作环境下,长期稳定输出,并持续提高水平的能力。
何为工程能力?
在实际工作中,绝大部分人都是在团队协作的环境下工作,因而就要求我们有“协作”的行为。换句话说,工程能力要求我们怎样才能变成一个更好的 Team Player。
工程能力的第二个要求是长期稳定。这与我们在 LeetCode 上刷题不同。在实际工作中,用多快的速度写完代码其实没那么重要,毕竟未来还需要修改。所以更重要的是,我们要写出更好改、更好读、更容易懂的代码。
我要强调的是,TDD(Test-Driven Development,测试驱动开发)是目前最具工程效能的开发流程。
最具工程效能?
首先,在团队协作的环境下,做 TDD 时需要先对需求进行任务拆解。换句话说,当任务拆分完成后,实际上就向团队中的所有人表明了我们是怎么理解需求的,将计划怎么去实现它。
而是需要把每一步理解到位,把任务切实有效地转化成一个或多个测试。如果能转化成测试,说明真的理解了需求。反之,则说明理解不到位。
TDD 这种自动化执行的方法,不仅可以帮助我们验证当时对于需求的理解、产生了什么样的偏差。也很容易帮助我们追溯 Bug 是怎么产生的,以及为什么会产生。在此基础之上,我们的输出才是长期稳定的。这就是我在强调的测试的两个主要目的:发现错误和定位错误。
第三个要求是持续提高我们的水平。一方面,在使用 TDD 开发的过程中,我们对需求和架构会有越来越清晰的认识,而需求和架构也会直接反映在任务列表中。事实上,在任务列表中,当产生了越来越清晰的任务,越来越容易转化成测试的任务时,我们的能力本身也就提高了。
TDD 的整体工作流程
很多人在学 TDD 时有一个很大的疑惑:不知道测试从哪儿来。因为当我们看 Kent Beck 的书时,会觉得他天马行空,好像随意写写就出现了很多代码。这背后其实是有很多考量的。
他的考量就是把需求先分解成功能点,由功能点再沿着我们对架构的理解,分解成功能上下文。然后再从上下文分解成具体的任务项,由任务项去写测试。这才是更完整的 TDD 的流程,而测试也是从这儿来的。
同样的问题还有重构。一个很容易跟它混淆的概念是重写,就是拿到代码后,在这上面直接重写一遍。但重构是有一个严格的定义。重构讲的是,我希望它的功能不变,结构变得更好。也就是代码功能本身不变,但是需要让代码结构变得更好。这意味着什么呢?意味着重构调整的是架构。
TDD 实际上并不是一种编码技术。因为它并不能驱动我们在任务项中把功能都实现出来,它真正驱动的是架构。这正是我们讲的编码架构师,是真正的实干型而非 PPT 型架构师。
在团队中推行 TDD 失败,从来都不是大家不会先写测试,不会进入红 / 绿循环造成的。而是因为没有有效地维护架构愿景,不知道应该按照什么样的方式进行需求分解。
可以说,在做任何软件开发时,理解需求、懂得架构,都是我们开始的前提和出发点。TDD 就是以这种形式告诉我们,必须以一种能被消费、能看得见摸得着的方式向别人展示“我真的懂了需求”。而我真的懂了需求,是因为我可以把需求分解成功能点。我真的懂了架构,是因为我可以在功能点内对架构进行上下文的切分。
在我们软件行业,大家非常关注自己个人的技术水平,而不强调工程实践的能力。所以我们行业里普遍缺乏这两种能力:
- 给我一个需求,我能够恰如其分地分解成对应的功能点;
- 给我一个架构愿景,我可以把功能点切分成对应的功能上下文。
最难掌握
将任务列表与测试直接关联在一起。