【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

敏捷咨询工具箱(二)──OO 训练营

  • 2010-12-31
  • 本文字数:2911 字

    阅读完需:约 10 分钟

犯错误是最好的学习方式

──莎伦·德雷珀

背景

我们为客户提供咨询,刚开始做了很多敏捷的实践,包括:持续集成、测试驱动、用户故事需求分析、迭代开发等等之后,发现如果再想深入下去,就会面临一些“硬骨头”:遗留系统和开发设计能力的问题。在一些客户那里,他们产品有 10 多年了,但是很少有人新加程序文件,写代码习惯于复制粘贴,都是在已有的类和函数上修修补补。团队缺少追求好代码的品质和能力,到处是大函数,上帝类(超大类,任何功能变化都要修改此类),重复代码,混乱逻辑,开发和维护成本太高。作为一个顾问,如何才能从根本解决这样的开发设计能力问题呢?

在 ThoughtWorks,如果招聘了一个没有经验的开发人员,会把他们送到印度的 TWU(ThoughtWorks University) 培养 2-6 个月,OO 训练营是开发人员的主要课程之一。它专门用来训练开发人员如何使用面向对象,如何进行测试驱动开发。通过这样的训练之后,开发人员可以很快的掌握面向对象开发和简单设计能力,养成追求好代码的品质。所以,我们也为客户的团队引入了 TWU 的 OO 训练营活动。

活动方式

clip_image002

OO 训练营的培训方式和我们传统的“填鸭式”教育完全相反。它采用的是苏格拉底式教学法,顾问不会给你任何标准答案,而是通过问题的引导,让学员自己一步一步找到最佳的解决方案。我的 OO 训练营的组织方式一般是:

一、顾问提出需求

顾问在训练营活动会扮演着客户的角色。活动一开始的时候,会以客户的身份提出一个需求,让大家去完成。例如:要求建模一个长方形。

二、简单设计

以分组讨论方式做一个简单设计,一般从如下三个方面进行设计。

  1. 类名是什么?
  2. 类的职责是什么?对于复杂需求,可能会要求画一个简洁的 UML 对象关系图。
  3. 类的测试用例会有哪些,并且找到第一个测试用例

讨论结束之后,每组介绍一下各自的讨论结果。通过分组讨论和顾问的引导,对建模一个长方形需求一般会得到如下的设计结果:

  1. 类名是: Rectangle
  2. 类的职责是计算周长和面积
  3. 计算周长的测试用例:
  • a. 正常场景。如果长是 2,宽是 3,那么周长是 10
  • b. 异常场景,宽为 0 的情况。如果长是 2,宽是 0,那么应该抛出异常
  • c. 异常场景,宽为负数的情况。如果长是 2,宽是 -3,那么应该抛出异常

这些测试用例完全是由学员自己设计出来的,没有标准答案。作为顾问只是引导大家,让每组的测试用例更具体和全面。假设没有一组学员没有考虑到异常情况的测试用例,这时也也不用指出来,等后面代码展示的时候,再指出这个问题,因为犯错是最好的学习方式。

三、测试驱动(TDD)开发

学员根据设计和讨论的结果,用测试驱动的方式进行结对编码开发。要求先写单元测试,写完一个单元测试之后,运行测试失败,然后再去写业务代码。如果没有失败的测试,不允许写一行业务代码。这样严格的要求,让大家养成测试驱动开发的好习惯。

两个人一组使用结对方式进行开发,要求使用乒乓式的结对方法。假设是 A 和 B 进行结对开发,A 先写一个测试用例,编译通过但是测试失败。然后把键盘和鼠标交给 B,B 写业务代码,让测试通过,然后为 A 再写一个失败的测试。通过这种乒乓的方式,一个人写测试用例,一个人实现业务代码,并且不停的变换角色。这样两个人可以很好的进行配合,互相给对方出“难题”,一个人在写实现的时候,另一个人会思考下一个测试用例会是什么。

有的时候,我们会对团队提出一些更高的要求。比如编程过程中不允许使用鼠标,一切都是快捷键操作,这样能提高开发的效率。编程过程中不允许使用复制和粘贴功能,如果是相同的功能或者代码,第一应该考虑到的是如何进行功能重用,而不是复制一遍,这样可以杜绝这样错误的编程习惯。

四、代码展示和顾问点评

写完代码之后,每个人开始展示自己的代码。这时,顾问就开始从代码里面寻找代码怀味道 (Bad smell),告诉大家什么样的是好代码,什么样的是坏代码。坏代码会有哪些危害,让后让大家重构。

例如:在实现长方形周长的时候,有人实现了 getLength 了 getWidth 方法,把长方形的长和宽的数据暴露出来了。那么这就是一个代码坏味道(Bad smell),顾问会指出这个问题,告诉大家面向对象最重要的一个特征是封装,不应该把数据直接暴露出来。因为数据暴露出来之后,一方面造成数据的依赖和耦合,另一方面其它代码在调用长方形这个对象的时候,也许会拿到长和宽的数据自己进行运算,这样就破坏了封装,对象之间耦合增大,并且容易产生重复的代码。然后提问大家,正确的做法应该是什么?

答案应该会是长方形不应该把长和宽的数据暴露出来,所有长方形相关的运算和逻辑都应该在长方形这个领域对象里面进行。这也正是面向对象设计的一个重要原则:Tell don’t ask 的体现。通过这样的引导的方式,带领大家一步一步找到正确的面向对象设计方法和原则,同时纠正那些错误的编码和设计习惯。

每次活动就是类似这样的流程。顾问提出需求,然后是讨论和设计,结对开发,最后展示代码和点评。一轮结束之后,顾问又给大家一些新的需求,进行第二轮,如此一直的循环下去。

经验和教训

我多次为客户的团队组织过类似的训练营活动。最长的一次坚持了 3 个月,每周 2 次,每次两个小时,完成了 OO 训练营的所有课程。坚持参加完这个活动之后,开发人员和技术 Leader 的都能真正的全面掌握面向对象设计方法和原则,并且把这些用到自己的项目中。下面是我的一些经验和教训:

  • 活动时间安排。如果每次活动 2 个小时,一般是安排在下班左右,一小时工作时间和一小时个人时间。因为大部分团队都有交付的任务和压力,完全占用工作时间不现实。
  • 家庭作业。由于我培训的一些团队技术基础不是很好,大部分开发人员无法在 2 个小时内完成编码任务。所以我会把没有完成的任务留作家庭作业,让大家在活动之后完成,这样在 OO 训练营的时候主要是进行设计讨论和代码的展示点评。这样也有一个好处,每个人都会有时间进行独立思考,对代码进行重构产生一个更好的设计。
  • 活动整个过程是以引导为主,让大家自己进行编码、重构和讨论,自己解决问题,寻找设计的最佳解决方案。顾问只是担任一个类似主持人的角色。

参考资料

如果你也想在自己的团队或者公司引入这样的活动,下面一些资料可供参考:

关于作者

钱安川,ThoughtWorks 公司高级软件咨询师、敏捷过程教练、资深讲师、Team Leader、开发者、 BeiJing Open Party 组织者和主持人。个人博客:敏捷开发训练

2010-12-31 06:242588

评论

发布
暂无评论
发现更多内容

Go语言并发编程核心-Channel的典型应用场景分析

Jack

我用ChatGPT的一些实践案例

石云升

AI ChatGPT 三周年连更

Django REST项目实战:在线中文字符识别

TiAmo

django RESTful 三周年连更

用Python也能画图?用Python来画个“python”

Bob

Python

2022-04-25:给定两个长度为N的数组,a[]和b[] 也就是对于每个位置i来说,有a[i]和b[i]两个属性 i a[i] b[i] j a[j] b[j] 现在想为了i,选一个最

福大大架构师每日一题

golang 算法 rust 福大大

异步编程|五分钟让你学会局部刷新Ajax技术

浅羽技术

Java ajax js jsp 三周年连更

成立3年,云服务厂商火山引擎全景扫描

B Impact

陆奇:“模仿”微软Copilot,结构性代际因边际成本转为固定成本

B Impact

磁盘I/O性能监控的指标

阿泽🧸

三周年连更 磁盘IO

测试需求平台10-DBUtils优化数据连接与SQL Limit实现分页

MegaQi

测试平台开发 三周年连更

IDEA用上这十大插件绝对舒服

越长大越悲伤

IDEA idea插件

Qz学算法-数据结构篇(查找算法--插值、斐波那契查找)

浅辄

数据结构 三周年连更

OpenHarmony设备开发常用接口

鸿蒙之旅

OpenHarmony 终端设备开发 三周年连更

跨平台应用开发进阶(五十七):uni-app 通过 overrideUrlLoading 实现拦截 webview 窗口的 URL 跳转请求

No Silver Bullet

uni-app 跨平台应用开发 三周年连更 webview 窗口 URL 跳转请求拦截

TPU、TensorFlow—谷歌云“增强”AI 芯片团队,与微软云竞争AI云份额

B Impact

Kafkaide让IDEA开发者不在游走

扬_帆_起_航

kafka kafka manager

全面解析|搞懂Nginx这一篇就够了

浅羽技术

Java nginx 反向代理 服务器 三周年连更

OpenHarmony接收指定网络的状态变化通知

坚果

OpenHarmony 三周年连更

Sam Altman:巨型AI模型时代已结束, GPT-4是OpenAI最后成果

B Impact

【云原生】Docker之创建并进入mysql容器

A-刘晨阳

MySQL Docker Linux 三周年连更

OneNet服务器LWM2M物联网协议(智能井盖方案)

DS小龙哥

三周年连更

响应系统设置的事件

智趣匠

Configuration 响应系统 三周年连更

2023 年 10 个最佳 Linux 桌面发行版,每个都是那么的漂亮!

wljslmz

三周年连更

阿里云DTS数据同步实施

乌龟哥哥

三周年连更

零代码以“王者荣耀”为例解析设计七原则,助你面试拿“五杀”

陈言必行

设计原则 三周年连更

Java 继承 Minio 实现文件上传、文件下载、文件删除等功能

Java架构历程

三周年连更

Prometheus实战-从0构建高可用监控平台(二)

小毛驴的烂笔头

Linux Prometheus

灾备的级别和等级划分

穿过生命散发芬芳

灾备 三周年连更

音视频八股文(5)--SDL音视频渲染实战。会使用就行,不需要深究。

福大大架构师每日一题

音视频 SDL 流媒体 福大大

美国To B软件公司受到ChatGPT“威胁”解析

B Impact

如何将 Java 文件转换为 InputStream?这两种方法很管用!

wljslmz

三周年连更

敏捷咨询工具箱(二)──OO训练营_研发效能_钱安川_InfoQ精选文章