管理不懂技术能行么?扫盲软件开发的基本常识

2020-01-06 04:51

  【导读】:如果你有不会写代码却要管理程序员的领导或上级,那本文就是要给他们扫盲软件开发的基本常识。比如:为何软件开发工期难以估计、为何开发速度那么慢、为何程序员要“浪费”时间写测试以及做代码审查(Code Review)?

  没人想交付延迟的、超过预算的软件,我从没见过一个软件开发者会大早上起床后心里想着“我就想把工作干得很差劲,我怎能让老板花更多钱呢?”但是,有太多的软件项目进行得都并不顺利。而且对于每一个新项目来说,似乎在加快软件开发速度方面的压力变得越来越大。所以,如果我们正在从事软件开发的工作,那么我们应该怎么做呢?我们应该如何在不降低软件质量的前提下加快开发速度呢?

  虽然历经 50 多年的历史,已推出无数方法、建议和书籍,但是 IT 项目仍总是经历失败。——Susan Moore [1]

  现在,我不是以某种专家的身份在这儿写东西。我从没运营过自己的软件公司,也没传播从丰富的学术研究或对照实验中提炼而出的理念,我写这篇文章是为了组织我自己的想法,因为我想要设法了解我所看到的周遭所发生的一切。

  为了正确地看待此事,我们首先需要搞清楚为什么要开发软件?所有软件生产的意义是什么?我们为什么最开始要做的就是开发软件?咱们暂且把开源当做房间里的大象搁置一边,先来探讨一下商业软件。咱们先从生意说起。

  按照我的理解,为了达成一笔成功的交易,我们首先应该找到使人们痛苦的东西(找痛点),可能是一种隐喻形式的或字面形式的痛苦(但通常是隐喻形式的),然后我们以钱作为交换,为他们提供减少痛苦的方法。例如,人们发现编程很难(很痛苦),所以开辟了编程书和编程课的市场;有些人不喜欢他们自己的外表,所以带动了健身、化妆品、美容等等整套完善产业的发展。生意从某种程度上给客户传达的观念是它们可以减少客户的痛苦(或对痛苦的感知),而且如果人们相信我们可以减少他们的痛苦,那么他们就会很乐于给我们付钱。

  当你接受了其实“产品”、“设计”和“工程”仅仅是同一件事的不同方面这种观点时,事情便都会进展得更好。——Greg Veen

  如果我们能够很好地做到“理解他人”,那么软件开发这项活动就能稳步推进。在软件开发过程中,我们会更加了解那些我们致力于解决的问题,所以我们可以开始设计更优的解决方案,因而我们创造的软件产品也需要有所改进。为了实现此目标,我们需要一支敏锐的开发团队、一支可以快速传播价值并且迅速应对变化的团队,这是软件开发实践中的核心目标。正如 Dan North 指出:

  “软件开发的目标是持续尽力降低软件开发时间对于业务的影响。”——Dan North[4]

  所以,拥有一支敏锐的开发团队至关重要。但是如何能够拥有一支敏锐的开发团队呢?你会:

  我们有很充分的理由做任何这种事:如果你想要维系你那支敏锐的开发团队,那么就要对团队中的每个人都认真上心。运行快的计算机和优良的科技研讨会使开发者表现得更好,这种对开发者的投资总有一天会得到回报。但是这种投资对留住优秀的开发者更有用,而我们想要组建的是一支敏锐的开发团队。

  所以如果不给开发者提供他们所想要的,那么我们该做什么呢?简单的答案是,去问开发者。但是,请在合适的时间,用合适的方式问他们。我们需要理解的一点是,开发者往往是天生的问题解决者。优秀的开发者热爱他们的工作,热爱的原因是他们整天能解决有趣的、复杂的难题,并且能够因此而挣钱。优秀的开发者陶醉于迎接复杂的挑战并且找到简约漂亮的解决方法。所以他们应该能想出精彩的点子以变得更加敏锐。但是许多组织鼓励开发者专注于错误的问题,这种鼓励可能既不是深思熟虑的也不是有意而为之,但是却时常发生。

  但是,这样做使得这些额外人员成为了开发者面向世界的接口。与外部持股者进行协调沟通的是项目经理和业务分析师,尤其是项目经理非常在意项目的交付。项目经理向管理部门汇报情况,管理部门关心的是:

  于是我们可以理解为什么之后项目经理开始变得专注于预测项目了。他们想要计划、结构、评估,他们想要知道什么时候在发生什么事。当他们向管理部门汇报的时候,所做的预测和估量会让他们显得更称职,所以他们才会向开发者探讨预估、报告和截止日期。所以之后,开发者开始专注于预估、报告和截止日期,他们将精力集中在这些预估和预测性上来让取悦项目经理。

  但是这样做有一点不如人意的是,预估和预测性都是不可能解决的问题。每次一个开发者开始着手一个新任务时,他们就面临一个不安的事实:任何一个给定的任务背后都可能有一个潜在复杂性的大坑,也可能没有。我们都希望任务是简单的,但是它有可能并不简单,你永远都不会知道。这时霍夫史达特定律就起作用了:

  霍夫史达特定律:事情总是要比你预期的花费更长的时间,甚至当你把本定律考虑在内时也一样。——Douglas Hofstadter[6]

  一个项目经理向一个没经验的开发者问项目的估算,这个没经验的开发者告诉了一个他们认为合理的估算,然后项目经理回去根据估算情况得出截止日期和相应的计划。优秀的项目经理为稳妥起见,甚而会在此基础上加上一点“富余”。但是之后不可避免的事情发生了——项目落后了。所以开发人员开始为赶在截止日期到来之前完成任务,开始加班加点地工作。但是长时间的工作使得开发人员疲惫不堪,他们便开始犯更多的错误。而且不仅如此,项目仍然在落后。项目经理需要知道到底是什么耗费了这么长时间,所以苦恼的开发者图省事,开始投机取巧偷工减料,这一过程中,程序漏洞源源不断地出现,所以此时产品不仅延迟了,而且漏洞频出。

  这种情况传达了一种消极的客户价值。当然这种延迟的、漏洞频出的产品可能仍然能够解决某种程度的客户痛苦,但是这些漏洞带来了新的痛苦,这又需要耗费时间来进行修复,这样客户就会对我们可以帮助他们的能力丧失信心,这使得他们更不想为我们付钱,到头来无人从中获益。

  一个项目经理来找有经验的开发人员问预算,开发人员便会回复他一个大到离谱的数据,但同时又小到使这个项目还不能立马被取消。接下来,项目经理(销售人员)回头开始质疑这个荒谬的数据:“那个预算看上去比我们希望的多一点,我们有没有可能缩减一下,让预算少点?”这时,有经验的开发者便会问:“我们着手需要的预算是多少?”销售人员回复他一个数,然后有经验的开发者揉揉她的下巴说:“预算有点紧,但是我们会尽量做。这样的话我们难以满足所有要求,只能提供最基本的性能。”然后她会在自己看上去不会不称职的前提下,预估他们可以承诺交付的是多么有限,并且这是她可以承诺的所有。这样的话,如果她最后交付的比自己先前承诺的更多,那么每个人都很开心。但是甚至在这个情况下,霍夫史达特定律还是会出现,过不了多久,我们就会像从前一样,在赶最后期限、交付低质量代码的泥潭中苦苦挣扎。

  预算是软件开发过程中一项必不可少却令人生厌的东西。不幸的是,人们往往以为编软件就像建房子或修车一样,承包商或参与的机修工在客户审批工作前,应该能很好地对要完成的工作提供一个可靠的预算。[……]然而对于定制软件,很多系统都是从零开始搭建,而且通常组装、最终运行、应实现的功能、完成的时间等等都在随时发生变动,因此在工作之初,你要选的方法和最终达成的效果都是不确定的,所以很难知道到底什么时候可以完成。——Steve Smith[7]

  我这儿的观点不是说要抱怨软件预算,大家都知道它虽然令人生厌但又十分必要,就怪这种软件预算会陷入一种恶性循环。为了赶截止日期,我们投机取巧偷工减料,交付低劣的代码,还一直互相保证我们过后终将回头将代码进行完善,但是“过后”再也不回来。如果我们回头修复那些漏洞的话,我们就已经在下一个阶段中又落后了。所以我们构建的一切都建立在脆弱的、杂乱一气的代码上,这些代码难以应对快速的变化。而且一旦困在这个循环中,那么开发者的注意力将难以继续集中在解决客能户痛苦上,相反,他们将会专注于诸如以下的问题上:

  有什么可能的方式能使我们最快地将任务标为“已做”并且让项目经理不要再烦我?

  我怎样才能尽可能少接触脆弱的代码呢?因为这些代码我接触得越多,它们崩溃的可能性越大。

  我怎样才能在这笔巨大而过火的技术债务中,竭力维持让我引以为豪的那一小块代码呢?

  我怎样才能向那些不知道我在干什么,或者不知道问题的复杂性的人们证明我的决定是对的呢?

  当客户开始抱怨那些我没有时间修复的软件漏洞时,我怎样才能将责任推到其他人身上呢?

  我怎样才能在我的简历中加入一些流行语,帮我另找一份不这样混乱不堪的工作?

  我没见过有开发者想要交付一份延迟的、满是漏洞的软件,但是我们因为想要他们速度放快,所以给开发者不断施压。他们为了取悦我们也答应照办,但是由于预估往往是错误的,所以导致他们深陷泥潭,在重压之下交付软件。他们为了取悦我们,加班加点工作,但又在软件开发中偷工减料。因为大家一直在催问他们“完成了吗?”使得他们在软件质量上做出妥协。最终没有人开心,软件仍然拖延,仍然满是漏洞。

  所以我知道的大多数开发者都在工作中尽其所能,但却深陷困境。他们为了赶进度忙得焦头烂额,甚至连怎么变得“更快”都顾不上想。因此他们把精力集中在了错误的问题上,他们重点关注的是如何让自己活下来。好比当你饿得快要死了的时候,你很难再去关注为退休攒钱的事儿了。也好比当你因为一个延迟的项目一周连续工作七天后,你很难再去计划怎样才能做得更巧。所以第一步应该承认,想要项目做得更快就需要投资,而且如果事情进展不顺,那么也同时需要时间/财政投资和情感投资两项。

  之前,我建议去问问开发者怎样才能减少软件开发时间对业务的影响,但是当开发者处于“赶进度”模式时,我们不可能得到从他们那儿得到很好的回复。当我们进入这种环境问道:“我们怎样才能开发得更快?”可能会得到两种回复中的一种:

  “我们需要出走两年,然后重头再来。”这种情况通常在开发者已经被技术债务彻底压垮时发生。技术债务太繁重了,所以他们感觉唯一的出路就是宣告破产。他们这样做可能也有一定的道理,但与此同时,我们可能并没有相应的预算作为支撑,而且当我们过后重建的时候市场必然不会一成不变。

  “我们已经开发地更快了,我不敢相信你竟然觉得你只用半个小时的头脑风暴就能修复这个复杂的问题!你怎么敢?!”这种情况通常在开发者觉得自己被迫发行低质量代码时发生。他们感觉当客户抱怨漏洞时,自己受到了客户的谴责。而且他们的愤慨很可能是有一定理由的。开发者怀着这种心态是不会帮我们的,除非我们可以向他们表达我们听到了他们的心声。他们需要知道我们理解他们的顾虑,我们同样也需要表明我们正在严肃地考虑做一些改变。

  在以上两种情况中,开发者的顾虑是正当的,但他们只关注了自己。我们希望创造一种每个人都为将软件开发时间对业务的影响降到最低而努力的环境。如果开发者不能摆脱这种心态的话将难以达成以上愿景。一切策略开始的前提是,向他们表明我们正在严肃地考虑做一些改变,这通常包括寻找减压的方式,即使那只是暂时的。

  但是即使这样,开发者仍然只会关注自己,除非再做一些改变。他们关于如何提升自己的工作成效会有大量的主意,其中一些想法可能很不错,但是有风险。我们需要让开发者转移对自身压力的关注,而将注意力集中在将软件开发时间对业务的影响降到最低上。我们需要让他们直面客户痛苦。

  我们接下来该如何使开发者直面客户痛苦呢?不计其数的人已经对此写过详尽的文章,所以这里我只是轻描淡写一下。这儿按照从最低效到最高效的顺序有三条观点:

  这在业界被称为喝自己的香槟,或吃自己的狗粮。这样做的好处是使开发者变成了产品的用户,所以任何明显的错误或问题也会令开发者自己感到烦恼。这种方法存在一个问题,那就是开发者并不是典型的用户(大多数时候)。开发者使用软件的方式通常有别于大多数的客户,所以尽管这样可以帮开发者修复主要的漏洞,但是可能无法为典型的使用案例提供很好的见解,而且这也并非一直具有实践性。比如说,假想我们正在为牙科保健员生产一个SaaS产品,这时开发者可能很难将这SaaS产品融入他们的工作流。

  一个更佳的方式是鼓励开发者参与到一些产品的支持团队中去。(他们可能需要极强的鼓励。)这张方式可以让开发者亲自体验客户痛苦。所以,他们接电话或收邮件(或推特,或其他种种)时,客户告诉他们问题所在。开发者做这件事长达一定时间后,他们也将会开始发现常见问题的规律,他们会注意到一次次涌现的问题。无需重复听那些相同的牢骚会成为修复软件可用性问题的一大动力。不幸的是,人们几乎不会联系支持部门告诉他们产品运行得多么棒,所以得到的反馈是有点偏见的。

  这种方法是最不方便的,因为它需要最多的组织进行协调,但这也可能收获最好的结果。利用这种方法,开发者可以得知正常人是如何在现实生活中使用软件去做实在的事的。他们能看得到好的、坏的和丑的。

  长期持续这样做是一件辛苦的事,需要耗费精力,需要进行组织,而且大多数开发者会对此有一种本能的抵触。我写这个感觉有点笨拙,因为虽然我理应做这件事,但我并没有经常这样做,但我相信值得付出努力做这件事。

  使开发者直面客户痛苦是一种用悉心努力克服认知偏见的训练过程。这是一条“让人学会谦卑”的漫漫长途。我们开发者往往认为我们要更聪明,而且许多开发者还要更加聪明,但是我们并不是无所不知。也许我终于搞清楚了一元绑定运算和操作组合的关系,这很好,但是这并不意味着我知道了我们客户每天使用我们的软件时会遇到什么。使开发者直面客户痛苦提醒我们自己我们所真正了解的东西是多么有限。

  在我的经历中,开发者越孤立于周遭,生产的最终产品越差。大多数团队层次中,有一层为业务分析师,他们认为让开发者免于接触用户是他们的工作,反之亦然,其实这样做是没有用的。若创造了一个开发者对于用户一无所知的环境,那么这种状况是非常危险的。——Jeff Atwood [9]

  现在,所有这种面向客户的温情举措非常模糊,都存在一个明显的问题。简单来说,这并没有让开发者的开发速度更快。事实上,这夺走了本应该用来编程的时间,所以可以认为这反倒使得开发速度变得更慢。所以我为什么认为以上说法对呢?简单来说就是如果你工作奋进的方向是错误的,那么开发速度的提升没有丝毫意义。使开发者直面客户痛苦重要的是方向而非速度。

  我们想要可持续性地将软件开发时间对业务的影响降到最低,我的假设是如果你为开发者指引了正确的方向,那么你可以在此基础上咨询他们接下来该如何做的意见。如果我们让他们落实他们的意见,那么我们便应该能看到结果。

  理想地来说,这是一个持续推进的过程。我们问开发者他们是否有任何能够加快软件开发速度的方法,然后我们对提供的方法进行试验,几周之后再回来,打听进展状况,继而再去问开发者加速的方法。就这样一直问他们,直到你每次你连问都不用问就可以直接进入他们的工作区域。他们于是开始这样说:“我们所做的路由引擎的重构真的成果不错。但是我觉得如果我们把那种逻辑的一部分移出来,放入微服务层,那么我们就可以更快地进行缝补和撕毁。”你可能并不知道那意味着什么,但是如果我们看到漏洞减少、客户更加满意,那么大家就都成为了赢家。

  具体到你自己的团队,用什么样的方式询问他们取决于你自己。有些人喜欢头脑风暴研讨会,另一些人更倾向于调研或一对一专访。每种方法都有其不同的优缺点,但是无论你选择哪种方法,请确保弄清了限制。如果你仅有一笔很小的预算,要明说。如果没有灵活延长任何截止期限的余度,请告诉开发者。假设你拥有聪明的、能干的开发者,他们能够把以上这些都考虑在内。而且如果他们没搞明白,甚至在你多次解释说明后仍不明白,那么你也从中学到了点东西……

  务必在探讨限制时小心谨慎。如果你告诉开发者没有预算、截止期限是定死的、没有一丁点回旋的余地……那么他们无疑将回复你他们无力帮助,这种情况下你应该格外小心。高质量软件若想要提高生产速度,就需要花费金钱。开发者需要知道我们愿意为他们和他们的工具投资。如果没有预算、没有延长截止期限的余地、没有情况好转的迹象……那么聪明的开发者就会去考察其他方面,这种做法让我喝彩。这是一种没有胜方的局面,这种局面会吸引情感投资。向开发者展示我们在乎、并且愿意向他们和他们的未来投资,向他们解释我们目前正处于资源严重受限的困境,这样他们便可能会愿意想一些创造性的解决方案帮我们挣脱当前困境。

  我在这儿要做一个较大的假设,我假设当你向你的开发者解释限制时,他们都很聪明,完全能够理解。最大最显而易见的限制就是我们并没有无穷无尽的金钱去挥霍。开发软件很费钱,远比大多数人预期的或意识到的要多得多。好的软件开发者得花不少钱去请。我在这儿的假设是有至少有一个或两个聪明的开发者可以能够理解以上情况。

  可悲的是一些开发者就是不理解,那么你该怎么做呢?答案并不简单,但是我推测开发者不理解的原因是他们从来都没有机会以更大的眼光去看待问题。他们只被要求做去做不现实的预算和加快开发速度,并没有从客户或那些付他们薪水的人的角度去考虑问题。唯一使他们开始理解的方式就是有人展示给他们看。

  我要做的另一个大假设当我们把开发者带到委托人员面前时,我们相信他们不会让公司难堪。当然了,也有很多次我和委托人开会时,开发者说了蠢话或宣泄不满的情况,毕竟并不是每个人都做好了站在幻灯片前展示推销游说本领的准备。但是如果我们相信一个开发者能够仅礼貌地握握手打招呼,那么他们当然至少也能做到坐在一角,静静地看人们使用软件?[10]也许他们需要有人首先能带带他们。但是如果从来没被给过机会,一个人还能以什么方式去学做一个组织优秀的大使呢?

  咱么假设你的团队里全是聪明的开发者。当你让他们出主意时,他们可能首先想出许多听上去是反直觉的东西,比如像:

  所有的这些技术都会降低开发速度……TDD很像是完成同样的结果却用了两倍的代码量,而结对编程就像利用了两个高产的开发者却将结果削减了一半。我能理解一些质疑,但这不只是时髦的流行语(大多数的这些技术已应用了几十年之久),它们自然有存在的充分理由。

  让我试着用类比解释一下:当你开车时,你要系安全带。近些天我们希望车能自带安全气囊和防撞缓冲区,但是当你想开得真的很快时,你要戴赛车安全带、头盔和防火服,我们还会将翻滚护架、气流偏导器和粘型轮胎加到车上。这个类比不完美,但是希望你能明白我想表达什么。首先,一些诸如TDD和代码检查的方式会使你开发速度变慢,他们会变得笨拙,不易习惯。但正是这些保障团队更加安全地加速进展。

  我们非常确信当维护费用——许多时间和金钱考虑在内时,TDD节省了时间和金钱。——Eric Elliott[11]

  像TDD和持续集成这样的技术是关于提升软件质量的,这意味着生产中会产生更少的漏洞。在漏洞流出前将其捕获意味着会减少重做的次数、减少尴尬、更愉悦客户。问题通常会被更快(耗资更少)得被修复。随着时间流逝,不耗费在修复漏洞上的时间增加。另外,这些技术支撑下写出的代码往往更为灵活,更易改变或再用。这意味着我们可以花费更少的时间去对抗脆弱的代码库,能花费更多的时间去添加新的特征或修改功能。最终结果是软件更好,开发速度更快。

  这样的要点是减少从写代码到交付客户所经历的时间。这样的话,开发者可以观测到新的代码是如何减少客户痛苦的。掌握了客户反馈,那么他们可以进一步提升代码等等,这样我们就创造了一个良性循环。

  我们的转变就是从真实用户那儿获得反馈的时间大大减少。——Phil Wills[12]

  如果你在过去几年一直在追随IT发展趋势,那么对良性循环一定很熟悉。良性循环听上去很像持续交付,但是这种流行语并不是重点。持续交付只是一套实践的标签而已。而且,这些实践能够提供紧凑的反馈环,反馈环能够使得我们在提升速度的同时减少风险。

  这样做有一个很好的理由。我们所建立软件的环境不仅麻烦而且复杂,一个麻烦的系统有许多部分,实则让一个专家都要好好理解这么多的部分是如何结合在一起的。但是一个复杂的系统不仅仅有许多部分,而且所有的部分都彼此连接,相互作用。所以,当你改变了一小部分后,那么整个系统可能都会因而发生变化。一个经典的案例就是眼镜蛇效应:

  英国政府对德里的有毒眼镜蛇数量非常担忧,因此每捕杀一条眼镜蛇,政府就会发放一笔赏金。起初这是一个非常成功的策略,因为很多人为了赏金开始大量捕杀眼镜蛇。然而最终,激进大胆的人为了收益反而开始专门饲养眼镜蛇。当政府意识到这种情况后,这一奖励计划便被取消了,眼镜蛇再无价值,于是导致饲养眼镜蛇的人只好将其放生,所以野生眼镜蛇的数量进一步增多。[13]

  在复杂的系统中,很难预测一次给定改变所可能产生的影响,这是因为做两次相同的改变可能产生截然不同的结果,第一次改变能引起一定的系统反应,在下一次中会完全不同。这样会导致非本意的结果,使计划和预估出现问题。

  理解复杂性的方式是,在空间中的动作会导致空间发生变化,而且原因和结果只有在回顾时才能被理解。——Liz Keogh[14]

  那么我们在一个复杂的环境中如何设法去完成每件事?专家建议“探索、感知并且回应。”换句话说,创造紧凑的反馈环去评估哪些事能成或不能成。然后我们尽快重复此动作,保持小变化、短周期。因此,与失败关联的风险也控制到很小,恢复的成本也更低。我们要做很多小实验,保留工作正常的,恢复工作失败的。

  在一个复杂的环境中,你探索、感知并且回应,你做一些可能失败的小风险的事,这会帮助你对你所应对的环境有所了解,这是高反馈、风险和创新的沃土。——Liz Keogh[15]

  我们不能仅靠“最佳实践”建立一支高水平开发团队。不幸的是,软件开发中几乎没有捷径,但是当我们能够谦卑地承认我们并非无所不知时,总能利用一些方式能干得很好。

  让开发者直面客户痛苦缩小了反馈环,这使得我们确信如果我们加快开发速度,那么我们一定在正确的方向上加快速度。一旦达成了这一点,我们便能够以一种适应给定情况的方式进行持续的改进了。

分享到:
相关阅读
文章评论 · 所有评论
评论请遵守当地法律法规
点击加载更多
© 2016-2018 12小时新闻网 http://www.12hnews.com/ 中国互联网举报中心
违法和不良信息举报:lobtom@163.com