[封面图]

封面图

敏捷–高效软件开发之道

不管路走了多远,错了就要重新返回 – 土耳其谚语

软件项目的成败,依赖于整个项目团队中所有开发成员的技术水平。对他们的培训,以及他们各自的能力高低。

就像成功的冲浪手一样,开发人员必须也是技术扎实、懂得掌握平衡和能够敏捷行事的人。不管是预料之外的波浪冲击,还是预想不到的设计失败,在这两种情况下敏捷都意味着可以快速地适应变化。

  • 个体和交互胜过过程和工具
  • 可工作的软件胜过面面俱到的文档
  • 客户协作胜过合同谈判
  • 响应变化胜过遵循计划

敏捷的精神

我们都见过因为开发过程的冗余、笨重、繁杂而失败的项目。世上应该有一种更好的软件开发方法–只关注真正重要的事情,少关注那些占用大量时间而无甚裨益的不重要的事情。

敏捷:一种把以人为本、团队合作、快速响应变化和可工作的软件作为宗旨的开发方法。

敏捷方法可以快速地响应变化,它强调团队合作,人们专注于具体可行的目标,这就是敏捷的精神。它打破了那种基于计划的瀑布式软件开发方法,将软件开发的实际重点转移到一种更加自然和可持续的开发方式上。

它要求团队中的每一个人都具备职业精神,并积极地期望项目能够获得成功。它并不要求所有人都是有经验的专业人员,但必须具有专业的工作态度–每个人都希望尽最大可能做好自己的工作。

  • 不能只在项目结束的时候才开始测试
  • 不会在月底才进行一次系统集成
  • 不会在一开始的时候就停止收集需求和反馈

越早发现问题,就越容易修复问题,所以应该就在此时此刻把问题修复。

这种持续前进的开发思想根植于敏捷方法中。它不但应用于软件开发的生命周期,还应用于技术技能的学习、需求采集、产品部署、用户培训等方面。它包括了软件开发各个方面的所有活动。

软件开发是一项非常复杂的智力活动,你遗留下来的任何问题,要么侥幸不会发生意外,要么情况会变得更糟糕,慢慢恶化直到变得不可控制。但问题积累到一定程度的时候,事情就更难解决,最后无法扭转。面对这样的问题,唯一有效的解决方法就是持续地推进系统前进和完善。

所以,你要防微杜渐,把问题解决在萌芽状态,你要探索未知领域,在大量成本投入之前先确定其可行性。你要知错能改,在事实面前主动承认自己的所有错误,你要能自我反省,经常编码实战,加强团队协作精神。

敏捷的修炼之道

敏捷开发就是在一个高度协作的环境中,不断地使用反馈进行自我调整和完善。

敏捷团队的工作和生活方式:
首先,它要整个团队一起努力。敏捷团队往往是一个小型团队,或者是大团队分成的若干小团队(10人左右)。团队的所有成员在一起工作,如果可能,最好有独立的工作空间,一起共享代码和必要的开发任务,而且大部分时间都能在一起工作。同时和客户或者软件的用户精密工作在一起,并且尽可能早且频繁地给他们演示最新的系统。

你要不断从自己写的代码中得到反馈,并且使用自动化工具不断地构建(持续集成)和测试系统。在前进过程中,你都会有意识地修改一些代码:在功能不变的情况下,重新设计部分代码,改善代码地质量。这就是所谓的重构,它是软件开发中不可或缺的一部分–编码永远没有真正意义上地”结束”

要以迭代的方式进行工作:确定一小块时间((一周左右)的计划,然后按时完成它们。给客户演示每个迭代的工作成果,及时得到他们的反馈(保证方向正确),并且根据实际情况尽可能频繁地发布系统版本让用户使用。

单元测试:《单元测试之道Java版》
自动构建:《项目自动化之道》 持续集成

魔鬼和这些讨厌的细节

1
2
魔鬼:"干吧,就走那个捷径。真的,它可以为你节省时间。没有人会知道是你干的,这样你就会加快自己的开发速度,并且能够完成这些任务了。这就是关键所在。"
天使:"先难后易。我们首先要解决困难的问题,把简单的问题留到最后。"

平衡的艺术

一件好事做得过火或者被误用,都是非常危险的。所以,我们希望保证你能真正从这些习惯中获益。

态度决定一切

选定了要走的路,就是选定了它通往的目的地 –Harry Emerson Fosdick

影响软件开发因素:个人情绪、办公室的文化、自我主义、记忆力等。它们混为一体,态度和心情瞬息万变都可能导致巨大的差别。

专业的态度应该着眼于项目和团队的积极结果,关注个人和团队的成长,围绕最后的成功开发工作。由于很容易变成最求不太重要的目标,所以我们要专注于那些真正的目标。集中精力,你是为做事而工作。

欲速则不达
对事不对人
排除万难,奋勇前进

只有在你对项目、工作、事业有一个专业的态度时,使用敏捷方法才会生效。如果态度不正确,那么所有的这些习惯都不管用。有了正确的态度,你才可以从这些方法中完全受益。

做事

1
2
魔鬼:"出了问题,第一重要的是确定元凶。找到那个白痴!一旦证实了是他的错误,就可以保证这样的问题永远不会再发生了。"
天使:"指责不会修复bug。把矛头对准问题的解决办法,而不是人。这是真正有用处的正面效应。"

如果你说的话只是让事态更复杂,或者只是一味地抱怨,或者伤害了他人的感情,那么你无意中在给问题火上浇油。相反,你应该另辟蹊径,问问”为了解决或缓解这个问题,我能做些什么?”

在敏捷团队中,大家的重点是做事。你应该把重点放在解决问题上,而不是在职责犯错者上面纠缠。

世上最糟糕的工作就是和一群爱搬弄是非的人共事。他们对解决问题并没有兴趣,相反,他们爱在别人背后议论是非。他们挖空心思指手画脚,议论谁应该受到指责。这样一个团队的生产力是极其低下的。

在敏捷团队中,情形截然不同。如果你向敏捷团队的同事抱怨,他们会说:”好,我能帮你做些什么?”他们把精力直接放到解决问题上,而不是抱怨。他们的动机很明确,重点就是做事,不是为了自己的面子,也不是为了指责,也无意进行个人智力斗角。

你可以从自己先做起。如果一个开发者带着抱怨或问题来找你,你要了解具体的问题,询问他你能提供什么样的帮助。这样简单的一个行为就清晰地表明你的目的是解决问题,而不是追究责任,这样就会消除他的顾虑。你是给他们帮忙地。这样,他们会知道每次走进你的时候,你会真心帮助他们解决问题。他们可以来找你把问题解决了,当前还可以继续去别处求助。

符合标准不是结果,敏捷团队重结果胜于重过程

如果你找人帮忙,却没有人积极响应,那么你应该主动引导对话。解释清除你想要什么,并清晰地表明你的目的是解决问题,而不是指责他人或者争辩。

切身感受 勇于承认自己不知道答案,这回让人感觉放心。一个重大的错误应该被当做是一次学习而不是指责他人的机会。团队成员们在一起工作,应互相帮助,而不是互相指责。

平衡的艺术

  1. “这不是我的错”,这句话不对。”这都是你的错”,这句话更不对。
  2. 如果你没有放过任何错误,就说明你可能没有努力去工作。
  3. 开发者和质量工程师争论某个问题是系统本身的缺陷还是系统增强功能导致的,通常没有太大的意义。与其如此,不如赶紧修复它。
  4. 如果一个团队成员误解了一个需求、一个API调用,或者最近一次会议做的决策,那么,也许就意味着其他成员也有相同的误解。要确保整个团队尽快消除误解。
  5. 如果一个团队成员的行为一再伤害了团队,则他表现得很不职业。那么,他就不是在帮助团队向解决问题的方向前进。这种情况下,我们必须要求他离开这个团队。
  6. 如果大部分团队成员的行为都不职业,并且他们对团队目标都不感兴趣,你就应该主动从这个团队中离开,寻找更适合自己发展的团队。

欲速则不达

1
2
魔鬼:"你不需要真正地理解那块代码,他只要能够工作就可以了。噢,它需要一个小小的调整。只要在结果中再加上几行代码,它就可以工作了。干吧!就把那几行代码加进去,它应该就可以工作。"
天使:"不要坠入快速的简单修复之中。要投入时间和精力保持代码的整洁。"

在工作压力之下,不去深入了解真正地问题以及可能地后果,就快速修改代码,这样只是解决表面问题,最终会引发大问题。快速修复的诱惑,很容易令人把持不住,坠入其中。短期看,它似乎是有效的。但从长远来看,它无异于穿越一片流沙,你也许侥幸走过了一般的路程(甚至更远),一切似乎都很正常。但是转眼间悲剧就发生了……

只要我们继续进行快速修复,代码的清晰度就不断降低。一旦问题累积到一定程度,清晰的代码就不复存在,只剩一片浑浊。这样的代码根本没有清晰度可言,它已经成为一团迷雾,无人能懂。

不要孤立地编码

孤立非常危险,不要让开发人员完全孤立地编写代码。如果团队成员花些时间阅读其他同事写的代码,他们就能确保代码是可读和可理解的,并且不会随意的加入这些”+1或-1”的代码。阅读代码的频率越高越好。实行代码复审,不仅有助于代码更好理解,而且是发现bug最有效的方法之一。

使用单元测试

另一种防止代码难懂的中技术就是单元测试。单元测试帮助你很自然地把代码分层,分成很多可管理的小块,这样就会得到设计更好、更清晰地代码。更深入项目的时候,你可以直接阅读单元测试。

切身体会

在项目中,代码应该是很亮堂的,不应该有黑暗死角。你也许不知道每块代码的每个细节,或者每个算法的每个步骤,但是你对整体的相关知识有很好的了解。没有任何一块代码被警戒线或者”切勿入内”的标志隔离开

平衡的艺术

  1. 你必须要理解一块代码是如何工作的,但是不一定需要成为一位专家。只要你能使用它进行有效的工作就足够了,不需要把它当作毕生事业。
  2. 如果有一位团队成员宣布,有一块代码其他人都很难看懂,这就意味着任何人都很难维护它。请让它变得简单些。
  3. 不要急于修复一段没能真正理解的代码。这种+1/-1的病症始于无形,但是很快就会让代码一团糟。要解决真正的问题,不要治标不治本。
  4. 所有的大型系统都非常复杂,因此没有一个人能完全明白所有的代码。除了深入了解你正在开发的那部分代码之外,你还需要从更高的层面来了解大部分代码的功能,这样就可以理解系统各个功能模块之间是如何交互的。

对事不对人

1
2
魔鬼:"你在这个设计上投入了很多精力,为它付出很多心血。你坚信它比其他任何人的设计都棒。别听他们的,他们只会把问题变得更糟糕"
天使: "对事不对人。让我们骄傲的应该是解决了问题,而不是比较出谁的注意更好。"

–2023-03-07 12:59

你很可能见过,对方案设计的讨论失控变成了情绪化的指责–做决定是基于谁提出了这个观点,而不是权衡观点本身利弊。我们曾经参与过那样的会议,最后闹得大家都很不愉快。

对一个明显的错误的常见反应

  1. 否定个人能力 ×
  2. 支出明显的缺点,并否定其观点 ×
  3. 询问你的队友,并提出你的顾虑 ✔

要专业而不是自我

1
2
多年以前,在我担任系统管理员的一天,一位资深的管理员和我一起安装一些软件,我突然按错了一个按钮,把服务器给关掉了。没过几分钟,几位不爽的用户就在敲门了。
这时,我的导师赢得了我的信任和尊重,他并没有指责我,而是对他们说:"对不起,我们正在查找是什么地方出错了。系统会在几分钟之内启动起来。"这让我学到了难忘的重要一课。

在一个需要紧密合作的开发团队中,如果能稍加注意礼貌对待他人,将会有益于整个团队关注真正有价值的问题,而不是勾心斗角,误入歧途。我们每个人都能有一些极好的创新想法,同样也会萌生一些很愚蠢的想法。

如果你准备提出一个想法,却担心有可能被嘲笑,或者你要提出一个建议,却担心自己丢面子,那么你就不会主动提出自己的建议了。然而,好的软件开发作品和好的软件设计,都需要大量的创造力和洞察力。分享并融合各种不同的想法和观点,远远胜于单个想法为项目带来的价值。

消极扼杀创新

你不需要很出色才能起步,但是你必须起步才能变得很出色 – Les Brown

团体决策的骆驼

1
2
3
集体决策确实非常有效,但也有一些最好的创新源于很有见地的个人的独立思考。如果你是一个有远见的人,有一定要特别尊重别人的意见。你是一个掌舵者,一定要把握方向,深思熟虑,吸取各方的意见。
另一个极端是缺乏生气的委员会,每个设计方案都需要全票通过。这样的委员会总是小题大做,如果让他们造一匹木马,很可能最后造出的是骆驼。
我们并不是建议你限制会议决策,只是你不应该成为一意孤行的首席架构师的傀儡。这里建议你牢记亚里士多德的一句格言:"能容纳自己并不接受的想法,表明你的头脑足够有学识"

设定最终期限。 没有最好的答案,只有更合适的方案。设定期限能够帮你在为难的时候果断做出决策,让工作可以继续进行。
逆向思维。 团队中的每个成员都应该意识到权衡的必要性。一种客观对待问题的方法是:先是积极的看到它的正面,然后再努力地从反面去认识它。
设立仲裁人。 在会议的开始,选择一个仲裁人作为本次会议的决策者,每个人都要有机会针对问题畅所欲言。仲裁人的责任就是确保每个人都有发言的机会,并维持会议的正常进行。
支持已经做出的决定。 一旦方案被确定了,每个团队成员都必须通力合作,努力实现这个方案。每个人都要时刻记住,我们的目标是让项目成功满足用户需求。

设计充满了妥协(生活本身也是如此),成功属于意识到这一点的团队。工作中不感情用事是需要克制力的,而你若能展现出成熟大度来,大家一定不会视而不见。这需要有人带头,身体力行,去感染另一部分人。

切身感受

1
一个团队能够很公正地讨论一些方案的优点和缺点,你不会因为拒绝了有太多缺陷的方案而伤害别人,也不会因为采纳了某个不甚完美(但是更好的)解决方案而被人忌恨。

平衡的艺术

1
2
3
4
5
1. 尽力贡献自己好的想法,如果你的想法没有被采纳也无需生气。不要以为只是想体现自己的想法而对拟定的好思路画蛇添足。
2. 脱离实际的反方观点会使争论变味。若对一个想法有成见,你很容易提出一堆不太可能发生或不太实际的情形去批驳它。
3. 只有更好,没有最好。
4. 不带个人情绪并不是要盲目地接受所有的观点。
5. 在开始寻找最好的解决方案之前,大家对"最好"的含义先达成共识。

排除万难,奋勇前进

1
2
魔鬼: "如果你发现其他人的代码有问题,只要你自己心里知道就可以了。毕竟,你不想伤害他们,或者惹来麻烦。如果他是你的老板,更要格外谨慎,只要按照他的命令执行就可以了。"
天使: "做正确的事。要诚实,要有勇气去说出实情。有时,这样做很困难,所以我们要有足够的勇气。"

有时,绝妙的计划会因为勇气不足而最终失败。尽管前方很危险–不管是真的鱼类或者只是一个比喻–你必须有勇气向前冲锋,做你认为对的事情。

假如要你修复其他人编写的代码,而代码很难理解也不好使用。你是应该继续修复工作,保留这些脏乱的代码呢,还是应该告诉你的老板,这些代码太烂了,应该通通扔掉呢?

也许你会跳起来告诉周围的人,那些代码是多么糟糕,但那只是抱怨和发泄,并不能解决问题。相反,你应该重写这些代码,并比较重写前后的优缺点。动手证明最有效的方式,是把糟糕的代码放到一边,立刻重写。

践行良好习惯

1
2
3
我曾经开发过一个应用系统。它向服务器程序发送不同类型的文件,再另存为另一个种格式的文件。这应该不难。但我开始工作的时候,我震惊地发现,处理每种类型文件地代码都是重复的。所以,我也配合了一下,复制了数百行地代码,改变了其中两行代码,几分钟之内就让它工作起来,但我却感觉很失落。因为我觉得这有悖于良好的工作习惯。

后来我说服了老板,告诉他代码的维护成本很快就会变得非常高,应该重构代码。一周之内,我们重构了代码,并立即由此收益,我们需要修改文件的处理方式,这次我们只需要改动一个地方就可以了,而不必遍查整个系统。

切身感受

1
勇气会让人不觉得有点不自在,提前鼓足勇气更需要魄力。但有些时候,它是扫除障碍的唯一途径,否则问题就会进一步恶化下去。鼓起你的勇气,这能让你从恐惧中解脱出来。

平衡的艺术

1
2
3
4
5
1. 如果你说天要塌下来了,但其他团队成员都不赞同。反思一下,也许你是正确的,但你没有解释清楚自己的理由。
2. 如果你说天要塌下来了,但其他团队成员都不赞同。认真考虑一下,他们也许是对的。
3. 如果设计或代码中出现了奇怪的问题,花时间去理解为什么代码会是这样的。如果你找到了解决的办法,但代码仍然令人费解,唯一的解决方法是重构代码,让它可读性更强。如果你没有马上理解那段代码,不要轻易地否定和重写它们。那不是勇气,而是鲁莽。
4. 当你勇敢地站出来时,如果收到了缺乏背景知识的抉择者的抵制,你需要用他们能沟通懂的话语表达。"更清晰的代码"是无法打动生意人的。节约资金、获得更好的投资回报,避免诉讼以及增加用户收益,会让论点更有说服力。
5. 如果你在压力下要对代码质量作出妥协,你可以指出,作为一名开发者,你没有职权毁坏公司的资产(所有的代码)

–2023-03-08 10:22

学无止境

即使你已经在正确的轨道上,但如果只是停止不前,也仍然会被淘汰出局。 –Will Rogers

敏捷需要持续不断地学习和充电。

软件开发行业是一个不停发展和永远变化的领域。虽然有一些概念一直有用,但还有很多只是很快就会过时。从事软件开发行业就像是在跑步机上,你必须一致跟上步伐稳步前进,否则就会摔倒出局。

学习新的技术和新的开发方法很重要,同事你也要能摒弃陈旧和过时的开发方法。换句话说,你需要懂得丢弃。

一个活力十足的敏捷开发团队需要有规律反复地做很多事情,一旦项目开始运作,你就要把握开发节奏。

跟踪变化

1
2
魔鬼:软件技术的变化如此之快,势不可挡,这是它的本性。继续用你熟悉的语言做你的老本行吧,你不可能跟上技术变化的脚步。
天使:跟踪技术变化。你不需要精通所有技术,但需要清楚知道行业的动向,从而规划你的项目和职业生涯。

赫拉克利特说过:”唯有变化是永恒的。”

迭代和增量式的学习 每天计划用一段时间来学习新技术,它不需要很长时间,但需要经常进行。记下那些你先学习的东西。
了解最新行情 互联网上有大量关于学习新技术的资源。选择一些公认的优秀技术博客,经常去读一读,以了解那些顶尖的博客作者们正在关注什么。
参加本地的用户组活动 听讲座,积极加入问答环节。
参加研讨会议
如饥似渴地阅读 关于软件开发和非技术主题的好书,也可以是一些专业的期刊和商业杂志,甚至是一些大众媒体新闻。

切身感受

你能嗅到将要流行地新技术,知道它们已经发布或投入使用。如果必须要把工作切换到一种新的技术领域,你能做到。

平衡地艺术

1
2
3
4
1. 许多新想法从未变得羽翼丰满,成为有用的技术。要正确把握自己投入的精力。
2. 你不可能精通每一项技术,没有必要去做这样的尝试。只要你在某些方面成为专家,就能使用同样的方法,很容易地成为新领域的专家。
3. 你要明白为什么需要这项新技术--它试图解决了什么样的问题?它可以被用在什么地方?
4. 避免在一时冲动的情况下,只是因为线学习而将应用切换到新的技术、框架或开发原因。在做决策之前,你必须评估新技术的优势。

对团队投资

1
魔鬼:不要和别人分享你的知识。你是因为这些知识而成为团队中地佼佼者,只要自己聪明就可以了,不用管其他失败者。

–2023-03-16 18:21:00

交付用户想要的软件

敏捷反馈

敏捷编码

敏捷调试

敏捷协作

尾声:走向敏捷