《敏 捷 教 练:如何打造优秀的敏捷团队》—11 代码整洁

举报
清华大学出版社 发表于 2019/10/21 21:15:11 2019/10/21
【摘要】 本节书摘来自清华大学出版社《敏 捷 教 练:如何打造优秀的敏捷团队》一书中第十一章,第11.1节,作者是Rachel Davies Liz Sedley,徐 毅 袁店明 译。

第11章

代码整洁

保持房间整齐干净,显然是很重要的;不然,时间一长它就变得没法住人了。同理,如果团队不花时间保持代码的整洁,代码就会变得既杂乱又脆弱,从而拖慢他们的脚步。作为他们的教练,你的职责是支持他们,让他们学会如何保持代码整洁、代码测试和集成。

让我们来看看,如何才能使团队关注代码的整洁,并开始尝试增量式设计、集体代码所有权和结对编程等一些敏捷实践。我们也会分享一些技巧,介绍如何发现并解决阻碍团队协同创建整洁代码的问题。

11.1  增量式设计

增量式设计很简单,就是拿点时间出来,一小步一小步地边做边改。设计改进变成了每一个开发人员日常工作的一部分。这活儿得在每个用户故事结束时干完,不能留到以后再去做。在这种工作方式下,在写测试时,为通过测试而编写代码时,甚至是在签入代码之前,开发人员一直都在思考着软件的设计。

然而,从预先设计到增量式设计,这种转变是一个挑战。花时间做软件设计还是编写代码实现更多用户故事,要帮助团队在这两者之间找准平衡点。


摆脱分析过度

项目开始的时候,团队经常因为分析过度(analysis paralysis)而迟滞不前。帮助他们摆脱困扰,还没产出可工作的软件之前,先别花太多时间用于思考设计。

尝试找出是什么在阻碍团队前进的脚步。他们是否试图找到适合未来所有需求的设计?是因为他们害怕现在的决定在今后无法扭转?提醒他们,可没有什么水晶球能帮助他们预测项目过程中将出现的所有新需求。继续进一步讨论也不太可能找到正确答案,反之,他们可以通过实现这些需求来证实自己的想法。

鼓励团队为现在做设计,只考虑当前需求,尽可能保持简单的设计。我们也不是说他们必须故意短视——在做设计决策的时候,团队要考虑到即将开发的用户故事。提醒开发人员,重做通常会改进设计。每重做一次设计,都会让设计精致,变得更具可塑性。

对前进的方向达成共识

架构设计方面的分歧同样也会阻碍团队前进。这些分歧通常在团队内各有所长的开发人员之间发生权力斗争的时候冒出来。一种常见的争论是在前端、中间件或存储过程中各分配多少逻辑。团队经常被卡在这里,因为他们不知道该怎样自行解决分歧。

如果团队陷入僵局,就组织一次团队研讨会,评估各种设计方案的利弊。可能的话,从团队外找个专家来参加研讨会,提供一个独立的视角。确保每个方案得到同样的时间和审议。建议团队把所有设计都写在白板上。这有助于将辩论的关注点从个性转移到问题上。鼓励团队选择一个设计在下个迭代先做起来,并且同意在下一次回顾会议的时候再看看还有什么担忧。如果担心团队内部有压力,也可以建议大家以匿名投票的方式来决定。


预留设计的时间

我们发现,比过度分析更常困扰团队的是一个相反的问题:没有花足够的时间做设计。开发人员总想节省设计的时间,因为从外面是看不见软件设计的,这意味着客户也看不见。在交付的压力下,开发人员往往就不知不觉地只写到代码可运行,却不清理设计;短期来看,设计省下来的时间能让他们更快交付用户故事。但是,不注重设计会导致代码变得难以理解,难以更改,最终减缓整个团队的速度,情况严重的话还可能导致整个代码库被丢弃。

在团队实现用户故事的时候,帮助团队时刻都将设计铭记在心。做规划时,提醒他们要在估算中为设计讨论和设计重构预留时间。给故事都加一个设计任务,这种办法行不通,设计不是可以隔开来单独完成的任务。设计得融入团队中所有开发人员进行开发的过程中。如果有些故事需要做进一步设计研讨,那就加一张卡片放到团队板上,提醒大家记得进行这个讨论。

还可以与他们共同工作,把设计评审加到他们的“完成的定义”(definition of “done”)中,帮助他们牢记代码整洁。他们可以制定一个团队公约,代码签入前必须交由其他开发人员过目,确保该代码(包括单元测试)至少能很容易地被另外一个团队成员理解。或者,他们也可以选择通过结对编程(pair programming)实现此代码,以便所有生产代码都是由两名开发人员结对写出来的。

找一块白板,让团队可以聚在一起进行非正式的设计研讨。确保白板放在开发人员座位附近,而不是放在会议室里,因为设计讨论往往是自然而然发生的。如果开发人员想讲点什么事,他只需要拿起记号笔,画幅草图帮着阐明自己的观点就行了。要想帮助团队在设计讨论中开始使用他们的新白板,可以自己先用起来以作示范。

若团队遵循了增量式的设计方法,他们对代码设计的关注会贯穿于每个故事的整个开发过程。他们会在实现代码之前先讨论设计,实现时也会继续清理设计。不管用哪一种方法,都有助于使设计一小步一小步地改变,而不是一次改变太多。鼓励团队使用重构每次只做一个小更改,而不是一次性翻天覆地、面目全非的大更改。

重构

重构(refactoring)是在不改变行为的前提下,提升软件设计的活动。每次通过一个小的改进小步地完成,比如,重命名字段(field)或提取方法(extract method)。每次重构之后,都应该执行测试,看看它们是否仍能通过运行,如果能通过那就可以签入代码。我们最喜欢的重构指南是Bill Wake的《重构手册》[Wak04][1],因为此书中包含有练习,你可以和团队一起做一遍。

image.png

image.png

要让代码变得更易于维护,可以从以下两方面入手进行重构:

 

l  通过重新组织以及重命名代码提升可读性

l  通过整合、删除未用代码减少冗余代码

可读的代码

团队需要编写很容易被团队其他人理解的代码,还得是自描述的,以方便未来几年的代码维护者。肯特·贝克(Kent Benk)在《实现模式》[Bec07]中如此陈述:“写出别人能读懂的代码不需要用到魔法。就像一切写作过程那样——了解你的受众,想好一个清晰的整体结构,描绘细节以充实整个故事。”

警告性注释
Rachel

我曾经注意到,开发人员的抱怨有时会写在注释里,它们通常可以提供一些有用的启示。如下注释来自于我曾参与过的一个项目:

/*理想情况下,这将作为延迟加载的一部分完成,当每个业务对象的get方法被调用的时候,加载会自动执行。然后,它会使用DAO找到自己拥有的对象,这就相当于有效地实现了一个实体EJB领域中容器管理关系(CMRContainer Manager Relations)的手工版本。然而,由于我们保持数据库连接并将连接从顶部会话层往下传至DAO,这一非常规做法让延迟加载变得不再可能。因此,在这里手工构造对象成了产生一个完整的tract对象以及它所有子对象的唯一方法。这是一种相当恶劣的做法,完全背离了DAO设计模式和服务层分离的思想,而且非常难以维护。*/

这个注释告诉我,团队中至少有一个开发人员在关心设计的完整性,但又让人感觉他们正在打一场必败的战役。我开始和这个开发人员一起努力向他的经理证明,迫切需要对紊乱的依赖关系进行重构,因为这是单元测试的障碍。

Beck继续说到,借助代码进行沟通的关键步骤在于,有意识地选择关注他人的需要。帮助团队开发人员领会写出其他人能读懂的代码到底有多么重要。实行集体代码所有权对此很有帮助,因为它让每个团队成员都能接触到其他写的代码。就在他们抱怨别人写代码的方式时,他们也会深刻意识到自己写清晰代码的必要性。结对编程则更进一步,让他们直接面对彼此的编程风格,能够了解到代码背后的思想,还有机会介入并教团队其他成员更好地表达自己。

我们建议你花一些时间通读代码,好好感受团队的软件设计水平。这可能会发现团队还有哪些地方需要进一步辅导,比如糟糕的设计或对需求的错误理解。甚至会从代码注释中找到线索,发现设计方面的分歧,帮助自己将团队内部尚未解决的问题暴露出来。

image.png

重构工具

工具使设计改进容易进行,因此也能够帮助团队坚持增量式设计。常见的重构若有自动化支撑(通过工具提供支持,例如ReShaper之于C#Eclipse之于Java),就能更快改动设计且更少出错。辅导团队让他们拿出时间来理顺开发环境。

仅仅安装完重构工具还远远不够,开发人员还需要知道在什么时候怎样使用它们。如果有些团队成员已经知道如何使用这些工具,结对编程会是一个非常棒的传递知识的方法。如果大家都是刚接触重构,那就在计划中预留出团队学习的时间。你可以鼓励团队办一次代码道场(coding dojo,参见10.1节的补充材料),以便讨论其代码与测试的设计。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。