这是关于一个项目的故事,与其它项目相比,既不非常复杂,也不是很简单: 一个应用程序与数据库以及其它两个系统通信。这在技术和架构角度都是主流,而在管理角度则是标准情况: 所有工作都应该在昨天完成,但还有很多没有完成的。简而言之,“这很难!” (这是开发者经常表达的一种情绪,但是谁都不会太大声地把它喊出来。)
为此我们创建了团队。雇佣了四十位员工并指定了他们的角色。我们把团队分为小组,并在不同的小组之间设置了一种契约。每个小组负责应对特定类型的要求。这样就形成了要求的流程。指定的小组会承受很大压力,并成为瓶颈: 在上游小组中会创建要求,而下游的小组会等待这些要求。对于那些有压力的小组中的要求,重要的事情会变为紧急的事情。我们必须在紧急的事情之中做出选择,以解决最亟待解决的问题。我们经常需要在任务之间切换,最终,这导致流程变得很慢。然后发布的最终日期临近了: 就在两个月之后。用户接受测试刚刚开始,但是不同组件之间冗长而痛苦的整合过程导致了测试的延迟。可能正是在团队之间创建的契约让整合变得如此复杂: 其中缺少一些必须的参数,日期格式不合适,只有部分错误代码能够得到解释……
在任何情况下,用户接受测试都会检测出很多的bug,而开发团队来不及解决,这样就无法对系统进行彻底的测试。
因此我们增加了更多人力。我们设置专门的团队来解决bug,在另一个地方的团队会完成开发,还有一个团队会整合不同的组件。但所有这些团队共享同样的代码,对某些代码做出的改变会影响其他团队所做出的修正。
接下来我们可以预测出这样的做法导致的结果: 开发者通宵加班,周末也要工作;最终日期被一再推迟,最初的工作任务范围发生了变更(减少了内容);然而,多亏了计算机科学的奇迹,应用程序最终发布并运行了!
这是多年以前的事儿了。我认为这是“要走的路”,并且所有项目都以相同的方式管理。从那开始,我经历了各种不同的情况,读了很多资料,并与很多人做过相关的讨论。现在我能够从不同的思想角度来看待这个故事。
创建IT系统是一种非常复杂的机制,其中不仅混合了技术、架构技能,还有管理以及与人相关的技能。在这两个领域有多种文化,但是关于构架系统的管理和人的部分,我认为Tom De Marco是我最喜欢的作者之一。我还记得他出版的两本书。在第一篇无标题的“软件工程: 关于谁的时代来临和消失的想法”中,De Marco讨论了对软件项目的控制(的幻想)。在第二篇“放松(Slack)”中,De Marco研究了管理学中的经典问题,并说明更多的放松能够如何帮助组织具有更强的适应性,最终获得更高的效率。
但是,带着这两篇文章中的想法,让我们回到故事中,看看如何才能避免很多典型的问题。
Tom Demarco向我们展示了一种方法来避免整体上陷入困境,也就是“每项功能都非常重要”的项目:
例如,你和团队的领导说,我时刻记着完成时间,但是我不会与你分享这个信息。当有一天我告诉你项目会在一周内完成时,你需要准备好打包,并把你所得到的东西作为最终产品发布。你的工作就是持续地为项目工作,按照相对值的顺序向其中添加内容,并在过程中持续地完成集成、编写文档以及验收测试工作。
如果不考虑实际的组织和技术上的问题,你需要有意识地对软件进行持续构建。团队之间的合同责任很有限,从而无法在技术上或者任务上组织它们,而只能在业务特性上做到这一点。从技术的角度,每个团队都是这样,要负责让完整的功能可以很好地运行。从管理的角度,经理和业务人员需要作出选择: 什么是必须需要的特性。根据我自己的经验,你在需要符合交付日期的环境中工作的时间越长,这种特性团队和组织就会对你起到更大的帮助。
我们在这里还要看看De Marco关于恐惧文化和它的特征是怎么说的:
“……在具有恐惧文化的组织中,会具有如下特征:
当我想到恐惧管理的时候,就会想象到一种专横的身体语言,他会在位置上对协作者大喊大叫,会用拳头敲桌子……这是非常具有讽刺意义的样子。这看起来像是在背后说人坏话,但是我们不得不承认,人们经常会处于这样的压力之下,难于提出警告,设定截止日期而不考虑团队是否能够承受,最终,团队会处于经理根据他们自己的地位所做出的提交压力之下。
当然,了解问题只是第一步。我们怎么才能解决呢? 当经理不了解风险所在,并且拒绝接受那些不可规避的风险,我们应该怎么办呢: 你需要选择,按优先级排序,并协商范围,以确保截止期限,或者把它延后。
这个任务绝对不是个简单的任务,我现在所能够给出的最佳答案就是backlog和燃尽图的组合。依我所见,在以下各种情况下,这会有些好处:
Brook在1975(我还没有出生)年声明了一条规则:
“向已经延迟了的软件项目中添加人手,只会使其延迟更严重。”
我们都已经对此深有体会。但是我们不得不承认,一般我们还是想要通过增加人力来保证在截止日期之前发布,而不是改变最初定义的范围,并保持最优化和合适的团队规模。Brooks对他的规则做出解释,其中有两个主要的观点。 第一点关注于新的团队成员,我们需要对他们进行培训,那会耗费现有人员的工作时间。第二点是一个“神话”,让我们相信开发任务可以任意分解,而不需要考虑工作中很多部分都需要智慧,并且还需要所有开发者之间必要的沟通。此外,我们还能发现更多与组织开发相关的困难,并且需要在所有开发人员之间共享同样的代码。这么多的细节会降低团队的生产力。
Tom de Marco为我们做出了他对Brooks的规则的理解,他称之为“人浮于事(overstaffing)”。
“按时完成并非是最重要的。重要的是看起来你已经做出最大的努力来按时完成。在这个“吃得少跑得快”的时候,对于你来说,使用少数(优化的)人员来运转项目是很不安全的。”
请再次读一下,这次慢一些。你不认为这是一种很有趣的观点吗? De Marco所建议的,或者说我的理解是,我们之所以不增加人力,是因为我们认为那会更快更好地完成工作。我们添加人力只是作为一旦失败时的借口。就像小孩子喜欢说的:“ 那不是我的错,我已经尽力了。”
这是多么自然的反应啊! 想要改变这种行为,首先需要改变我们的教育方式(并学着从失败和错误中吸取教训),并且组建一些组织,让失败成为其中的一种选择(当然不要太多)……
和通常情况一样,批评很容易,而艺术地处理则很难。那样,我们会注意到相同的错误一次又一次发生,而很少试一下其他方法(当然,这些方法也会存在其他限制)。“风险管理是为失败做计划的方法”(Slack, Tom de Marco),并且这可能正是我们擅长之处。Werner Vogels说过:“一切都一直在失败”。
他们所要表述的是: 我们很难避免失败。就像往山上滚石头的人一样,如果想要爬得更高,走得更远,就必须接受石头会落下的事实,那是通往成功的必经之路。所以拥抱它、处理它,并从中学习吧。
Tom De Marco告诉我们,想要管理风险,首先需要把它们识别出来,然后对其进行监控,设置指示器,当失败发生的时候会为我们提出警告。有时,我们需要找到其他方法。有些人需要培训。我们会开发软件的并行版本,这样,在做决定的最后时刻,我们就能够选择最适合的解决方案(精益管理把这叫做“基于设计设置(set based design)”原则)。
但是风险管理不仅仅是计划。从架构的角度来看,风险管理当然还意味着可依赖性的管理: 从灾难中恢复……但这种风险管理的方法意味着要为我们的系统制定架构——与业务部门的人员紧密合作——从而管理并拥抱所有这些错误。换句话说,就是尽可能地预测我们架构中可能发生的错误情况:
在现存的系统中,我们需要让它发展(而不是变革),从而确保这些已经检测出来的错误情况都被彻底修正。
但让我们现实一些。如果你是成本驱动的,那么你会发现所有非业务的需求都没有用。但是,最终我们对于应用程序的信心不正是就它管理错误的能力(弹性和可靠性)吗?绝对不是其它标准吗。
还有另外一个故事,属于另一个项目,既不非常复杂,也不是很简单。和其它所有项目的情况一样,其中有很多需要做的工作。开始时,IT和市场团队一起定义了清晰的路线图。
随着特性团队负责实现完整的用户故事、修正bug并部署他们的代码,平台变得越来越大。
当然,IT也遇到了技术问题。业务和IT部门需要一起来对路线图进行修正。最后期限已经到了,而有些特性被推迟实现了。那些都是优先级最低的特性。
当然,市场预测也不怎么好。CTO向平台添加的非功能特性(例如,记录所有用户行为的日志,或者当达到已知平台限制的时候限制访问)在发布平台的过程中非常有用,帮助市场团队改进了预测。用户愿意使用这个新平台,并且信任它。
在开放的空间中,墙上也充满了信息。燃尽图和累计流程图显示了团队的速度和问题,以及下次发布的目标……
在这个项目中,还雇佣了一位技术专家: 那是CTO不想放过的机会。
不管怎样,项目进行良好,并且还在运行中。技术人员们对自己所做的工作感到自豪……
查看英文原文:The Story of a Project