专栏首页Teobler的开发日记极限编程技术实践
原创

极限编程技术实践

上篇文章介绍了 TDD,这次我们将极限编程中的所有技术实践合起来一起聊聊。

重构

为了统一语言,我想有必要在开始讲重构前聊聊到底什么是重构。很多人讲到重构时甚至讲的是“将已有代码全删掉,重新写一遍这件事”,很显然这是重写不叫重构。

重构是改善代码结构的一种实践,但重构并不会改变由测试定义的行为。

重构应该是在不破坏任何测试的前提下对命名、类、函数和表达式进行修改。在不影响行为逻辑的情况下改善系统的结构。

发现了么,重构需要完备的测试做安全网,这层安全网能给你提供重构的信心和勇气。而 TDD 又能够提供重构所需的完备测试,这又是一项 TDD 优于后补测试的优点。TDD 和重构密不可分,所以有了

红-绿-重构

red_green_refactor

没错,又是这张图。上篇文章讲 TDD 时我用了这张图,但是刻意避开了蓝色的重构部分,现在是时候把二者结合起来了。一个完整的“红-绿-重构”循环应该是这样的:

  1. 创建一个失败的测试。
  2. 写出恰好能使测试通过的生产代码。
  3. 重构你刚刚写出的代码。
  4. 回到第一步。

“红-绿-重构”将写代码这件事分成了两个部分 - 编写可用的代码和编写整洁的代码,为什么需要拆开呢?

对于几乎所有人来说,光是编写可用的代码就已经很困难了,这个过程中我们需要不断调整,不断试错,更别说编写整洁可用的代码。因此,“红-绿-重构”将这两个部分拆开,先以脏乱的代码将我们脑子里的想法表达出来,一旦这些代码通过了你刚刚写下的测试,我们就开始重构刚刚写下的代码。

很显然,这是一个持续的循环过程,而不是一个定期发生的事情。也就是说,我们不应该先写一大堆实现,然后代码慢慢腐化,这个时候你才说,我应该重构一下这堆代码。你应该时时刻刻重构你一分钟前刚写下的代码。等你完成任务时,你的代码就是简洁可用的。

重构不应该是单独拿出来花时间做的一件事情,也不应该出现在项目的计划中。重构应该是日常开发中时时刻刻都在进行的活动,它就是开发活动中不可分割的一部分。

大型重构

这个时候想必有人会提出疑问:如果我发现系统当前的设计和架构无法支撑某一个需求的变更,我需要对系统进行一次大型重构该怎么办?

首先我们需要达成一个共识 - 系统架构不是一成不变的,是可以逐渐演进的。逐渐演进就意味着架构不会一次性从某个设计变成另一个设计。

所以这样的大型重构依然应该按照“红-绿-重构”的节奏来进行。既然现在的设计和架构无法支撑新的需求,那么就先重构一部分架构使其能够支持新的需求,然后添加新的部分需求功能。

在此期间,新的需求不断被实现,设计和架构也在不断被修改,这个过程可能是几天、几个星期甚至是几个月的时间。但是即使此时修改还没有完成,我们依然有信心在任何时候部署我们的代码,因为所有测试依然是通过的。

简单设计

simple_design

简单设计指的是:仅编写必要的代码,使得程序结构保持最简单、最小和最富表现力。简单设计是重构的目标之一。其规则如下:

  1. 所有测试通过。
  2. 揭示意图。
  3. 消除重复。
  4. 减少元素。

这里的需要既是执行顺序又是优先级,也就是说在写代码时应该优先满足上方的规则,然后在不破坏上方规则的前提下满足下面的规则。接下来我们一条条解释:

  1. 这条想必不用过多解释,代码必须能工作,这是最低要求。
  2. 代码工作起来后,不应该是一堆看不懂的字符。你写出的代码应该能表达你的思想,揭示你写这段代码的意图。也就是说你的代码应该易于阅读并能自我表达。要想做到这一点,拆分函数,表意的命名必不可少。
  3. 在具备上述两点后,我们应该找出和消除代码中的所有重复内容,毕竟重复可能是程序员最不能忍的问题了。此时的重构可能比起上面会难一些,大多数时候我们只需要抽出重复内容并调用即可,但是复杂情况我们可能需要使用一些设计模式来解决。
  4. 消除重复后,我们应该尽可能减少元素,比如类、函数、变量等等。

简单设计的目的和名字一样简单 - 尽量降低代码的设计重量,增加代码的可维护性。毕竟代码写出来是给人看的。

结对编程

how-do-we-pair

这又是一个争议颇多的实践 - 两人(或更多人)共同解决同一编程问题。结对的成员工作在同一台电脑上,共享屏幕、键盘和鼠标,当然也有许多工具支撑远程结对(比如 Intellij 的 code with me 插件)。

结对时有不同的角色。

在“驾驶员和导航员模式”中,“驾驶员”控制鼠标键盘,“导航员”则负责观察和及时给出建议;在“乒乓模式”中一个人先编写测试,另一个人让测试通过后编写下一个测试,再让第一个人编写实现,如此反复;当然还有老人写和讲,新人听和问的模式,这通常为了帮助新人快速熟悉代码库。

那么这么多模式,是不是结对的时候一定要遵循某一种模式呢?当然不是,大多数情况的结对其实并没有角色的划分。两者平等,合作解决问题。

相比起其他技术实践来说,结对是可选的,管理者不应以任何形式要求成员强制结对,有很多理由支撑独立写代码这件事。同时结对应该是间歇性的,团队内的成员应该有一段时间在结对,至于多久,不重要,这取决于个人和团队。

对于资深程序员来说,与初学者结对的次数应该超过与其他资深程序员结对的次数。对于初学者来说,与资深程序员的结对次数应该多于与其他初学者的次数。具备特殊技能的程序员应该经常与不具备特殊技能的程序员一起结对工作,使知识在各个成员间传播和交换。

为什么要结对

结对是团队成员之间共享知识并防止形成知识孤岛的最佳方法,这确保了团队中没有人是不可或缺的,此时如果一个人倒下,可以有别的人立马代替他的位置,继续向着目标前进。

同时结对可以减少错误并提高设计质量,两人在解决问题的过程中会有无数次讨论,两个人同时聚焦在同一个问题上。基于这个原因,已经有很多团队以结对的方式代替了代码评审(code review)。

代价

pair_programming_manage

这也是管理者们最关心的问题,我出了两个人的钱,你们却坐在一起做同一份事情?结对确实需要付出一些人力成本,并且这些成本难以估量,据 Bob 大叔的描述,研究表明结对的成本大概是 15%,也就是说如果结对,则需要 115 人来完成不结对时 100 人的工作量。

大家能轻而易举的看到结对的代价,却很难聚焦于结对带来的好处,因为结对带来的好处的确很难量化,也不易被发现,只有去实践了,你才能真正认识到它们。但遗憾的是,大多数人连尝试的机会都被剥夺了。

再谈极限编程

从两篇文章可以看出,极限编程的几个技术实践是相辅相成、缺一不可的。TDD、重构、简单设计,无论缺了哪一个,你的代码都有可能慢慢腐化,等到所有人都发现已经没办法再往代码库里添加新功能时,重写整个系统就又会提上议程,然后再次陷入无止境的循环。

而结对编程在其中又处于一个特殊的位置,它所能带来的好处其实也是不可或缺的,但由于种种原因又是比较难实现的一种实践。结对所带来的知识共享和代码质量如果你想做到可能得花费更大的力气。

敏捷的技术实践是任何敏捷工作中最本质的组成部分,是敏捷的核心。任何敏捷实践的导入,如果没有包含技术实践,都注定会失败。没有保持高技术质量的技术实践,团队的生产力将快速下降,最终陷入不可避免的重写循环。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 极限编程:价值观、原则和实践

    在软件工程这样一个快节奏的环境中,传统的项目管理方法不再可行。这意味着IT从业者必须找到新的方法来处理经常变化的开发任务。

    敏捷开发
  • 25.【Kevin聊敏捷】极限编程XP2实践

    18.【Kevin聊敏捷】敏捷项目管理之Sprint Retrospective 迭代回顾会

    开心的Kevin
  • 21.【Kevin聊敏捷】XP极限编程之12最佳实践(一)

    编程圈包括:结对编程(Pair Programming),代码重构(Refactoring),持续测试(Testing)

    开心的Kevin
  • 22.【Kevin聊敏捷】XP极限编程之12最佳实践(二)

    团队圈分为:代码规范(Code Standards),持续集成(Continuous Integration),集体代码所有制(Continuous Integ...

    开心的Kevin
  • 23.【Kevin聊敏捷】XP极限编程之12最佳实践(三)

    流程圈包括 每周40小时工作制(40-Hour Week),系统愿景(System Metaphor),小型发布(Short Releases),简单设计(Si...

    开心的Kevin
  • 24.【Kevin聊敏捷】XP极限编程之12最佳实践(四)

    极限编程要求至少有一名实际的客户代表在整个项目开发周期在现场负责确定需求、回答团队问题以及编写功能验收测试。

    开心的Kevin
  • 【云开发校园技术布道师】极限编程作品希望小帮手

    该小程序是云开发校园技术布道师极限编程,新生报名类命题的作品,意指给学校报名时候减轻负担,同时给学校增加广泛宣传力度,了解学校的各类事项。

    Ashenone62
  • 受国际软件巨匠之托,邀你赴一场十年之约 | 技术雷达峰会

    技术雷达是ThoughtWorks每半年发布一期的技术趋势报告,它不仅是一份持续的技术成熟度评估,其产生还源于ThoughtWorks另一个更大宏大的使命—IT...

    IT大咖说
  • 受国际软件巨匠之托,邀你赴一场十年之约 | 技术雷达峰会

    技术雷达是ThoughtWorks每半年发布一期的技术趋势报告,它不仅是一份持续的技术成熟度评估,其产生还源于ThoughtWorks另一个更大宏大的使命—IT...

    ThoughtWorks
  • DevOps工程实践技术培训课程

    你好, 我是泽阳。运营公众号已经有2年多了, 我会定期将技术总结经验发布到这里。在这个期间已经为超过7000+用户提供了文章服务。 除了文章形式外我更感兴趣的是...

    DevOps云学堂
  • 技术干货 | Serverless技术架构——极简运维 无限扩容

    移动互联网、物联网和大数据应用的快速发展极大地促进了人们对云计算的需求。但是让应用架构拥有良好的可伸缩性和高可用性并非易事,运维和管控庞大的基础架构更是极大的...

    Criss@陈磊
  • Jtro的技术分享:UGUI的极限优化

    关于unity中的UGUI优化,总有说不完的话题,优化方式有很多种,我今天要说的这种,算是一种简单的优化,实在开发人员觉得实在没有优化的方式采取的优化方式。 ...

    LittleU
  • 云开发校园技术布道师,第一次“4天极限编程”,记录一下

    在大学里面,学校会举办非常多的活动,通过这些活动,我们可以提高自身的能力。但是,在很多情况下,由于部分活动宣传的力度不够,因此造成许多人错失参加,为此,如有一个...

    T.
  • 语音消息技术实现技术实践

    消费升级的时代,搭配才能创造奇迹。文字是苍白的,语音是生动的,语音转文字是具备科技色彩的。文字一旦有了科技感,生活才能有质感。本课程以GME做“活化酶”,将详细...

    可可爱爱没有脑袋
  • 极限编程核心价值:勇气(Courage)

    勇气(Courage)是极限编程(Extreme Programming,XP)的核心价值之一。

    张高兴
  • 极限编程核心价值:尊重(Respect)

    尊重(Respect)是极限编程(Extreme Programming,XP)的核心价值之一。

    张高兴
  • 极限编程核心价值:反馈(Feedback)

    反馈(Feedback)是极限编程(Extreme Programming,XP)的核心价值之一。

    张高兴
  • 极限编程核心价值:沟通(Communication)

    沟通(Communication)是极限编程(Extreme Programming,XP)的关键核心价值。

    张高兴
  • 极限编程核心价值:简单(Simplicity)

    在编写 ASP.NET Core 项目时,深感项目设计的无力感,在软件设计方面我还有很长的路要走。我一直以来都把代码当作一种艺术的存在,认为自己是个“艺术家”,...

    张高兴

扫码关注云+社区

领取腾讯云代金券