敏捷质疑: 结对编程, 代码集体所有权
Q: 结对编程、责任共享,完全是胡说,代码找不到作者,开发人员哪里会有责任心!
A: 这个疑问基于一个假设: 开发人员的责任心来自于问责制度, 开发人员只有在恐惧的驱使下才会细心去编码.
我不知道你的职位是什么, 你或许是某个大中型企业的中高层领导, 或许手下有不少的人, 但你不会得到手下的尊敬, 他们只有"畏".
或许在对死亡之类的恐惧面前, 人类会爆发出强大的力量, 对于医疗系统, 军事系统, 心存敬畏之心是对的. 但日常生活中, 人们在荣誉而不是恐惧的驱使下, 更能发挥自己的潜能
Pair都希望通过展示自己的知识得到彼此的尊敬, 都希望代码轮转到其他同行手中时得到对代码质量的赞赏.
是的, 即使代码不署名, 团队依然清楚谁的代码写的好, 因为结对和轮换, 因为版本控制系统.
但是, 你, 管理者, 不需要知道哪块代码是谁写的, 不需要知道引起重大损失的Bug是哪个开发者引入的. 所有的事情都是整个团队一起完成的.
事实上, 你真正想知道的, 是整体上谁优秀, 谁需要提高, 或者谁真的不适合. 有其它比代码署名更好更有效, 而且不会把整个团队笼罩在恐惧的阴影下的方法.
Q: 那是什么方法?
A: 这涉及到整个考评体系的转变. 举个例子, 团队应该作为一个整体被考评, 客户的反馈, 带来的利润, 造成的损失, 都应该只到团队这一级, 荣辱与共.
团队内部每个成员的考评, 应该由团队自己完成, 成员之间经历了轮换结对, 谁优秀, 谁需要提高, 谁不适合, 都会有共识, 伪装不了.
Q: 你是说同行互评? 别扯了, 我只要弄好人际关系, 随你怎么评. 况且尤其是中国人, 抹不开面子, 怎么好意思当面说人家坏话.
A: 这是另外一个观念的转变, 必须借助于团队文化达成共识: 同行互评, 是帮助你发现自己的不足, 帮助你提高, 不是指责或贬低你. 如果你真的不合适, 同行互评会更快的让你认识到这一点, 从而努力提高或尽快选择其它的道路.
至于面子问题, 依然需要团队文化, 在秉承"沟通, 反馈, 勇气", 心态开放的团队里, 当面反馈反而更易接受.
另一方面, 大家都心智成熟, 如果一个人令周围的人都不爽, 难道真的因为面子的问题忍受下去?
Q: 怎么结对编程, 责任共享扯出这么大的动静来? 还要颠覆公司的考核体系?
A: 是的, 结对编程是 XP 实践中最具争议的一个. 反对它的开发者不在少数, 但更大的阻力来自老板的本能反对.
我们不幸生活在口号的时代. 或许领导们习惯了喊口号, 而从不考虑让口号"落地", 从不关注口号的实施. "合作"是不是能把耳朵磨出老茧的口号? 有什么具体行动? 结对编程就是最具体的一种合作啊.
老板们对它的质疑更多的是效率上. 其实就像TDD增加了整体代码量但不是工作量一样, 结对编程并非像直觉的那样降低了效率, 而是失之东隅, 收之桑榆, 甚至鱼与熊掌兼得.
几个俗套但不亲身体验就无法体会的论断:
-
不是总希望员工像驴一样干活不要偷懒吗? 为什么不让员工互相监督? 有人坐在旁边盯着你的屏幕, 你能上网,打游戏,和女朋友聊天? 天亮就干活,一直到天黑
-
不是总担心员工跳槽带来损失吗? 为什么不趁他还在的时候就让团队把他所有的知识都吸收干净?
-
不是总担心有人写烂代码吗? 不是一直觉得code review流于形式效果不理想吗? 还有比结对/轮换结对更彻底的code review形式吗?
-
不是总想取长补短, 优势互补吗? 不是总想达到"臭皮匠顶诸葛亮"的效果吗?
-
不是总担心新员工成长太慢吗?
-
不是总希望团队气氛融洽, 互帮互助, 没人跳楼吗?
Q: 我干嘛要把辛辛苦苦很多年积累的经验白白告诉别人? 我喜欢不可替代的感觉.
A: 是的, 本质上这是一个心理学和政治学的问题, 我也无法说服你. 但有几点, 还是要说一下.
-
独自解决一个别人无法解决的难题, 可以得到公司的承认; 把知识传授给团队, 至少也会得到团队的认可
-
解决已知问题的经验, 可以传授. 但当未知问题出现时, 多年的沉淀依然不可代替. 即使新手知道解决问题的一般原则, 真正熟练运用也需要岁月的历练.
-
如果你真的拥有智慧, 不必担心别人剽窃你的只言片语, 它们剽窃不了你的思想
如果你只是担心功劳会被别人抢走, 好吧, 我心理学和搞政治两方面都很差, 也没什么办法. 或许你可以坚持你不喜欢结对, 团队也不应该强求你结对.
Q: 有些老手不喜欢结对, 觉得新人不劳而获对他们不利, 不情愿, 怎么办?
A: 人们总是在心甘情愿的去做一件事的时候效率最高, 结对编程也应该遵循这个原则. 但并不意味着不做任何努力就放弃结对的纪律.
有些人可能凭直觉不喜欢结对, 但不曾真的尝试过. 你要想办法让团队的人真正花点时间试过, 再来下结论, 或许想法就会有所改变.
但实践初期, 有一个敏捷教练是有必要的. 结对涉及到人与人之间的合作, 性格的碰撞. 人的问题是最难缠的问题, 稍有不顺心, 就会夸大结对的负面效果, 比如彼此之间的争执, 互不相让等, 又或者总是由强势的人来主导, 平和的人总是被迫承担不喜欢的决定, 及它带来的后果.
敏捷教练可以发现这些问题的苗头, 并协助团队建立良好的纪律和习惯.
Q: 你刚才提到结对就是持续 Code Review, 可如果是两个新手结对, 代码质量还是得不到保证. 听说不鼓励新手结对, 是否真的?
A: 没什么真不真, 取决于你的资源情况. 两个经验丰富而又各有所长的人合作解决问题自然是最高效的. 现实生活中的最佳拍档不胜枚举, 甚至小说中人们也表达了对这种合作形式的强烈向往: 陆小凤与花满楼司空摘星, 楚留香与胡铁花姬冰雁, 四大名捕等.
然而确实团队中不是每个人都是楚留香. 事实上, 有经验的人能占到一半, 从而保证每对开发者都有一位经验丰富的人, 已经很不错了.
新人结对, 却也有另外一种效果, 以探索的方式成长, 虽然对团队短期的整体效率可能是个短板, 但对个人的成长, 会留下一些印象深刻的教训, 在未来的职业生涯中发挥作用.
有一些互相支撑的实践来提高新人结对的效率, 比如团队专用的开发空间, 实际上大家都坐在一间屋子里, 经验丰富的人听到新人Pair之间的讨论明显偏离正确的解决方案的时候, 随时可以加入讨论.
Q: 那互不相让怎么办?
A: 几种实践:
-
卷入更多的人讨论, 时间窗;
-
先选择其中一个人的意见做做看看;
-
不要选择夹生饭, 即妥协出来的方案通常集中了两种方案的缺点.
其实结对编程对开发者的冲击最大. 把你的工作重点从与机器打交道变成了与人打交道. 把你从虚拟的机器世界拉回到现实世界. 把程序员重新变回成"人", 练习人与人之间的交流.
工作上的争论, 对事不要对人.
Q: 强势的人主导怎么办?
A: 这个问题很快能够被整个团队发现. 团队需要和强势的人沟通, 提醒, 碰到问题不应该一味维护自己的方案. 但通常本性难改, 这时其他成员在发生此类问题的时候如果坚信自己的方案有可取之处, 要坚持不要放弃, 可以扩大讨论范围, 卷入更多的人讨论.
项目经理和初期的敏捷教练需要特别关注此类问题, 因为它有可能把结对变成假结对, 只是表面看是两个人.
Q: 难道一定要结对? 个人编码时代一样产生了无数优秀的软件, 而且更能体现作者的思想和个性.
A: "一定"这类词只应出现在几个基本定理中, 其它场合通常是错的, 而且总会给措辞追咬者提供把柄, 有时甚至你只是说某个东西好推荐使用, 他也能理解成你说的是"一定"要用某个东西
至少两个极端情形下, 结对并不强制:
-
复杂, 初期需要静心思考的问题, 可以分头行动, 各自有了理解或解决方案或时间窗到了再来讨论. 言语在思考的过程中也会帮忙, 但我们都知道对有些问题, 言语只会打扰思路.
-
一堆琐碎毫无技术含量的工作, 不得不手工完成, 只是考验耐心, 自然不妨分头行动, 效率肯定比结对要高
Q: 几对开发者同时讨论各自的问题, 太吵了!
A: 小点声.
Q: 又说Pair之间要交流, 要讨论以便周围的人听到后可以及时发现偏差以节省时间. 到底要小声还是要大声?
A: 安静的讨论
Q: 如果代码集体所有, 那某个模块出错,此时已经有超过5对开发者编辑过此模块代码,那么谁来改?
A: 团队来改. 如果要在某个模块上增加新功能, 此时已经有超过5对开发者编辑过此模块代码, 那么谁来添加?
Q: 我想修改某段代码, 想找原作者了解一下思路, 可根本不知道是谁.
A: svn praise/blame. 然而更应该发生的是:
-
TDD, 一旦改错单元测试用例会给你反馈.
-
轮换结对编程, 可能很多人都清楚那段代码.
-
简单设计, 代码不应该太复杂