这是一份迟到的小结,去年底组织完Global Code Retreat后,有些新的感受想要分享。结果一路拖延下来,又多了两次道场活动的收获。分别是3月份与亚光一起组织的上海敏捷社区道场,和4月底哈罗单车的内部活动。再次印证了当初的想法。
最初组织Coding Dojo的想法
一开始我是在公司内部组织的。主要原因是那时候刚刚通过个人练习,在掌握TDD上有所突破。因此非常兴奋,想要通过一起练习的方式把我学到的东西传达给其他人。
基于这个出发点,活动的形式大概是这样的:
- 首先进行了一次内部分享,来讲解TDD相关的概念,和具体的做法。
- 为了让参与者有直观的感受,第二次活动是展示形式的。由我演示用TDD一步步完成一个题目。
- 后面几次的活动是用MOB形式,一台连接投影仪的电脑,大家轮流上来写几分钟。旁边的人一起讨论分析。这样既可以保证整个过程采用了TDD的方式,又给了每个体验思考的机会。
-
在大家对TDD都比较熟悉之后,尝试了结对分组形式,每两人一组用一台电脑,同时写一道题目。然后留一段时间轮流review代码。
面临的挑战
看起来是费了一些心思逐步推进吧?活动的实际效果也确实不错。不过,让更多人掌握TDD这个目标,却没有达到预期效果。
那么面临的挑战是什么呢?
- 首先TDD是需要付诸实践的技能,所以单纯的宣讲作用是不大的。只讲红,绿,重构循环的话,几句话就说完了。讲得更深的话,没有实践也很难体会到。
- 现场演示呢,实话说压力还是很大的。众目睽睽之下脑子很容易短路。为了效果和面子不免要做充分练习,但是这样又有一些副作用。
- 太熟练了容易讲得太快,听众跟不上。
- 太熟练也会让人觉得只是这道题目的这种解法练习的次数多,所以才这么遛。对于方法本身还是持怀疑态度。
- 然后是轮流MOB的形式。每对轮换上来的人面临的心理压力和单独演示是一样的,还要理解前面一组的思路。所以往往有手忙脚乱,焦头烂额的情况。此外各组也可能思路有差异,无法有步骤的分解解决问题。这时
- 如果努力引导,把思路带回引导者自认为“正确”的路上。一来影响了每个人的参与度,也会让人觉得是不是仅仅因为你做过一遍知道答案了而已。二来,也不一定就能引导回来不是。😆
- 自由探索的话,一般来说由于思路反复和适应新方法的过程。往往在限定时间内进度是很有限的。虽然对于我来说这是意料中的情况,但是是否会打击初学者的信心就不得而知了。
- 最后结对同时进行,期待是分别练习前面的收获。不过由于上面提到的一些困难,往往实际上手进行时发现还有些点没有掌握,不免卡在某一步。由于分组的方式,难以充分讨论每组的详细过程和困惑。
所以一段时间的操练之后,发现大家对活动本身是比较满意的,但是却远未达到学会TDD的目标。
意料之外的收获
由于工作调整等原因,去年相当一段时间没有再组织道场活动,直到最近这三次。
这次由于对于对后续活动难以有很多规划,是抱着大家一起开心开心,感受一种不太常有的编码体验的态度进行的。在没有预设目标的情况下,反倒看到了代码道场活动的其它方面,以及可能的引入TDD的路径。
收获一,自己最关注的,未必是参与者感受最深的
就像前面提到的,Coding Dojo活动虽说是一般化的编程操练,但是一开始就与学习推广极限编程技能紧密相关,我也一直把学习TDD作为最核心的目标。然而,一位参与者的反馈却让我颇有感触:
头一次在掐表限时的环境下写代码,感觉非常新鲜。
听到这个感受时,我突然意识到,由于自己参与过多次道场操练,反倒已经看不到第一次参与者会注意的事情了。
- 比如限时,平时除了面试,几乎是不会遇到的。限时却又不要求完成就连面试也不会碰到。
- 比如结对,平时也只会有不常规的查错攻坚时才能体验。
- 比如代码review,虽然大部分公司流程里都会要求,不过现实中往往被进度压力追的无暇顾及,匆匆点过。像道场活动那样争先恐后的要求上台被review更是少而又少了。
- 比如重构,也是大家都提倡的。但是很少有机会说干就干,一群人注视着改善一段代码。
- 又比如单元测试,后面详细展开。
收获二,单元测试是很好的切入点
通常讨论起来TDD,不论是支持还是反对的,往往并没有把概念理的很清楚。有时候他在说,我们做TDD,往往实际说的是我们写自动化测试。
就我的观察,对于测试的接受程度,可以分为几级。
- 一切测试都是无用的,只有我的智慧和理性才是程序正确性的唯一保证。
这样的大神从来没见过。 - 端到端测试有用,单元测试无用。
往往潜台词是这种测试需要大量的精力。应该由专门的测试人员负责 - 单元测试是”正确“的事,但是对自己无用。
后半句一般不会实际说出来,从实际中可以表现出来。比如说起来应该写单元测试却从来不写。为了应付覆盖率指标写等等…… - 单元测试可以让我开发的更有效率。
达到这一步的程序员会很乐于自己去写单元测试。就算还没有掌握TDD,也只有一步之遥了。
从活动中观察到的,大部分人都处于第三级的情况,也就是说至少理论上认为单元测试是有必要的,但是另一方面,很少有人实际在写。
这几次活动没有特意强调TDD或者写代码的方式,只是倡导性的希望至少写一个测试。实际情况是这样的:
- 很多组都可以在限时内基本完成。整体速度高于强调按照TDD流程的操练活动。
- 有部分组会写测试。而不写的组往往是限于单纯的技术问题。比如不知道怎么引入测试框架,或者因为从来没写过,也不想在有限的时间里再去研究测试写法。
- 有些组没写测试,但是采用了其它方法对代码做了验证。比如main方法验证,打印结果值,做个简单UI进行手工验证等。
- 在每轮代码review时,很自然的会反映出测试的作用。比如,
- 你怎么知道自己完全实现了题目要求?
- 如果是xxx的情况输出会是什么?
- 咦?我明明调试的时候测过这种情况呀……
- code retreat活动中,同一道题目会反复写几轮。按照规则每轮都要删除代码从头开始。自然而然的就会有小组提出能否保留测试只删除实现代码。也就是说只要开始写单元测试很快就会认识到它的价值,并希望再次利用。
- 在重复多轮的活动中,会有越来越多的小组开始写测试,而且只要开始写,后面的轮次中都会保持或扩充测试集。没有人在尝试后又放弃了这种方式。
可见代码道场是个很好的机会让更多人体验到了单元测试对开发者的助益。也许要在日常工作中大规模使用,还需要克服种种困难比如良好的测试代码风格,依赖隔离等。但是只要开发者自己觉得这件事是值得做的,相信这些都不是真正的问题。
收获三,改变远比想象中简单
Code retreat 活动中同一道题目会操练好几轮,每轮有不同的挑战。其中一轮是完全不许使用鼠标。
大部分人的第一反应是”这怎么可能“——当然这不是真的极端困难的事,我也相信有人能做到,但我不是那种花那么多精力记满脑子快捷键键盘敲得飞起……
然而实际挑战开始后,有趣的事情发生了。
开始会有人完全无法工作了,或者不得不申请几次豁免,暂且移动一下鼠标看看需要的快捷键。
十分钟之后,没有一组还在研究鼠标键盘,全都进入到了代码逻辑的处理中。
这轮挑战结束,已经不再强制后,后面轮次大部分人会继续使用刚刚熟悉的快捷键。
也就是说仅仅十分钟,这件事就从“怎么可能”变成“自然而然”了。出乎我自己的意料。
仔细想来,其实在组织代码道场的活动中,我收获过很多这样的出乎意料。
- 担心气氛,因为你懂的,程序员很“闷”。
然而实际中我从未碰到过冷场的情况,相反往往嗨得停不下来。开始我归因为我们公司的气氛融洽,后来归于周末能来参加社区活动人的主动性。最后我发现,其实程序员本来就没那么闷嘛,特别是有个合适的问题的时候。 - 担心结对编程的接受度。
活动中大部分人都几乎是瞬间接受这个设定的。无论实际中这种配置多么少见。 - 一些实际工作中遇到过的棘手问题。
比如固执己见,过于尖锐的评判等等。事实上从未发生过……
最终我发现,在一个规则明确,目标可控,安全的环境中,大部分人都会更乐于作出尝试,更容易作出改变。
这可能是代码道场活动在具体的编程技能外,带来的更大的收获吧。