通常来说,致力于改善团队开发效率的同事会陷入两难的局面,要么他们会和他们所服务的开发者产生冲突,要么他们的时间都花费在一些截止时间遥遥无期的项目上面,因为大家对这些项目漠不关心。
之所以会发生这种情况,是因为开发团队认为有待解决的问题并非实际存在的问题。举个例子,你新加入一个团队,发现他们当前正在维护的代码复杂得无可救药,以至于没法编写测试,也没法轻易地对系统做更改。但是团队中的开发者们并没有意识到编写的代码过于复杂,也没有意识到正是这种复杂性导致了现在他们陷入了困境。他们感知到的只是:“我们一个月只能发布一次,在发布那天整个团队必须加班到晚上十点才能把工作完成。”
当效率改善人员遇到这种情况时,他们中的一些会忽略开发者们的抱怨转而一心工作在重构代码上。出于一些原因这通常起不了多大的作用,首要的问题是:管理层和其他的开发者都会对你产生抵触的情绪,使你的工作过程障碍重重。
如果抵触只是唯一的问题,那也不难克服。真正的问题是,即使大家都知道你的每一项工作任务都完成得极其出色,你还是会逐渐被公司疏离。你的经理们会将你边缘化,甚至尝试将你驱逐出团队。应付复杂的技术问题已经够麻烦了,没有必要再与全公司为敌。
随着时间的推移,负责效率改善的人员会对周围合作的同事形成一种敌对的态度。他们认为如果其他的工程师如果能够“使用我开发的工具”,那么所有麻烦都能迎刃而解。但是开发者最终并没有选择使用你编写的工具,所以你又凭什么认为你的工具举足轻重呢。
问题在于,一旦你开始忽略其他开发者的抱怨(又或者完全意识不到他们遇到的问题),你们之间对立的种子就已经种下了。它不是一个由好变坏逐渐腐化的过程。而是从一开始当你认为问题是这个,而其他开发者认为问题是那个的时候,矛盾就诞生了。
对于效率改善人员而言,这不仅仅意味着他们与公司之间产生了隔阂——还给他们个人带来了相当大的挫败感。毕竟人们想要把工作完成。他们希望工作最后有所产出,他们希望工作能带来积极影响。
如果你做了一大堆的重构工作,但是根本没有人继续维持重构后代码的简约,又或者你写了一堆没有人使用的工具/框架,那本质上你还是和什么都没有做一样,太令人沮丧了。
你应该怎么做
你应该怎么做?目前我们已经达成了一个共识是,如果你完全不认可(或者不知情)其他开发者遇到的问题,那么你可能会逐渐变沮丧、失落,甚至是以丢掉这份工作的结局收场。所以解决之道是什么?你应该完全遵从其他开发者的建议吗?毕竟能哄他们开心还能把工作保住。
坚持下来并不难(保住工作和哄某些人开心),至少在经过少许折腾之后吧。但你也看到这种处理问题的方式非常没有远见。如果同你工作的这些开发者确切知道如何将他们自己从深陷的泥潭中解救出来,可能从一开始就不会陷入此类麻烦当中。
情况有时候会更复杂——例如你需要和一个新组建的、负责旧代码库维护工作的团队一起工作,在这种情况下整个新团队成员都算是我所说的“效率改善人员”,又或者你也是这个新团队其中的一员。这只是许多可能中的一例。但不管怎样,如果你是提出解决方案的那个人,你需要面对我会在第40章中提到的问题。也就是当你在解决开发效率低下的问题时,开发者是你解决方案的用户。
你不能无脑地同意其他开发者提供给你的关于如何实施解决方案的建议。这么做可以在一定程度上哄这些人开心,但这终将会让系统变得难以维护,而且也仅仅是满足了那些叫喊声最大的用户的需求而已——他们很可能并不代表你的大部分用户。
如果你接受了他们的建议,那么你最终会得到一个设计混乱,甚至连真实用户需求也无法满足的系统,这再一次影响你无法得到晋升,失落连连。在解决开发效率这个领域下还存在一个特殊情况。如果只针对开发者提出的问题来制定解决方案,你永远不可能从根源上解决这些问题。
举一个例子,假如开发者向你抱怨他们某个千万行代码的单体二进制代码发布流程太慢了,接着你就把时间都花费在想方设法让发布工具变得更快的工作上,结局是多半你不太可能带来好的改善。或多或少能带来一些改善(让发布更快),但是永远也没有解决根本问题,根本原因是这个二进制代码体积太大了。
解决办法
然后又该做些什么?不按照他们说的去做意味着失败,按照他们说的去做带来的提升又不痛不痒。中间地带在哪?
正确的解决办法我会在第40章中给出,在那基础之上做一些小的修改即可。通过运用这个方法,我不仅解决了大型代码库中根深蒂固的问题,还改善了核心研发组织内的工程师文化。只要它能被正确执行,就会是有效的。
你要做的第一件事是明确开发者认为的问题所在。不要做任何的评判。四处走走和不同的人聊聊。但不要只询问经理或者是高级管理人员的意见。他们表述的和在一线开发的工程师表述的会完全不同。
多听听那些直接和代码库打交道的人的意见。如果你没有机会和每一位工程师交谈,可以先从与每个团队的技术管理者沟通开始。然后你可以和管理层聊聊,毕竟他们也有你需要予以记录和解决的问题,你需要对这些问题进行了解。但是如果你只想要解决开发者遇到的问题,你应该从开发者身上找出问题是什么。
在这个阶段我有一些个人的技巧可以分享。一般来说,如果你直接问开发者代码的复杂之处,他们不一定能回答上来。如果你问“什么地方过于复杂了”又或者“你认为的难点是哪”,他们可能想了半天也给不了你答案。
但如果你希望得到大多数开发者对于他们编写或使用的代码的情绪上的反馈,那么他们还是有很多话可以说的。我会问一些类似于这样的问题,“这份工作有什么让你感到闹心的地方吗”,“哪一部分代码你修改起来最不爽”,“代码库中有什么地方是你因为害怕改坏了而不敢修改的”。如果面对经理我会问:“代码库中有没有开发者常常抱怨的地方?”
你可以根据你的情况对这些问题进行调整,但请切记你是真心想要和开发者们进行一次对话——而不是机械地把问题列表读一遍而已。他们会说一些你有兴趣深入了解的事情。你可能需要把当中的一些内容记录下来。
在这项工作持续一段时间后,你大概就能察觉到这些抱怨中的共通点(或者某些共通点)。如果你阅读过我编写的另一本图书《简约之美》,或者你曾经从事过效率改善方面的工作,你应该能意识到问题的底层原因其实是某些代码过于复杂了。
这并不是我们想要寻找的唯一原因——即使没有和大家交谈我们大概也能猜出来。我们想要寻找一些更高层次的原因,类似于“构建二进制文件过于缓慢”。有更多类似的原因有待我们发掘。
相信现在你已经收集到了不少的信息,至于如何处理它们选项也很多。通常研发部门管理层应该会对你收集的一部分信息感兴趣,将这些信息汇报给上级能够增进他们对你的信任,并且有希望促成大家一致解决问题。这算不上是解决方案的一部分,但有时候你可以基于你对实际情况的判断决定是否有必要去做这件事。
个人信誉和解决问题
首先你可以从收集的信息中找到那些开发者已知的,且能在短时间(比如一至两个月)改善的问题,并给出解决方案。解决方案没有必要完全颠覆现有工程师的开发模式。事实上它也不应该这么做。因为当前变革的重点是为了建立大家对你工作的信任。
提升开发效率的成功与否,取决于你的个人信誉。
你可以预见总有一天你需要解决本质上的问题。只有当其他开发者对你有足够的信任,你才有机会朝那个方向努力,当你想要做出一些改变时,大家会相信你的解决方案是正确的。所以你首先需要做的事情是,在团队中树立自己的可靠形象。
你不需要带来巨大的、颠覆性的变革。这是你知道自己能做到的事,即使有点困难。如果这是其他人试图去做但失败了的事情,这会有所帮助,因为这样你也会证明,事实上对于这个别人可能无法处理的混乱局面(然后每个人都对整件事感到绝望,决定永远忍受这一团糟的生活,而且它无法被修复,等等),是可以采取一些措施的。
通过解决第一个问题,大家已经对你有了基本的信任,接下来你可以着手搜寻开发者真正面临的问题,以及最佳的解决方案可能是什么。这通常不可能一气呵成。此时你需要注意到另一个知识点——你不能一下子推翻并重建所有的团队文化和开发流程。你必须以渐进的方式,将变革逐步“渗透”到大家的工作中(人们通常会因为你改变了什么,或者改得面目全非,又或者第一轮变革并不起作用而感到生气),等到大家适应之后再考虑推进下一步工作。
如果你试图将变革一步到位的在团队内推广生效,一定会有人公开的反对你——这些反对的声音会让你的个人信誉荡然无存,还会使得你所有的努力付之东流。于是你又不得不回到之前提到的两个毫无建设性的解决方案——要么团队变得士气低下,要么毫无起色。所以你必须按部就班地展开工作。有的团队可以接受较大程度的变革,有的只能接受较小程度的变革。通常团队的规模越大,你执行的过程越要缓慢。
障碍
一般进展到这个阶段,你会遇到一些阻碍你工作推进的坏脾气的人。有时候这类人是高层人员,要么冥顽不灵要么只是不可理喻而已(你可以通过观察某人是否频繁地攻击他人来辨别这个人是否是不可理喻的)。在这种情况下你能继续取得多大的进展,部分取决于你的沟通技巧,部分取决于你希望执行下去的决心,但也有部分取决于你如何化解这种状况。
你应该找一批支持你的人,建立一个能为你付出的努力背书的核心圈子。绝大部分程序员还是帮理不帮亲的,即使他们口头上什么也没有说。
当有人提出他们的长远改善计划时,你应该公开鼓励他们。不要要求每个人都做出完美的改变——你的当务之急是凝聚你的“团队”来验证清理代码、效率提升的种种手段是有价值的。你还要负责营造志愿者文化或者经营开源项目——你必须非常地有感染力和友好才有助于这些工作的推进。但这并不意味着你应该接受糟糕的改变,但是如果有人想要做出改善,你应该至少对他们表示肯定和赞许。
有时十个人里有九个人想要做正确的事情,但他们的声音会被那个嗓门最大的人的声音所掩盖,以至于他们想当然地认为应该尊重那一个人的想法,而不是据理力争。所以你应该尽力争取这一部分人的支持,这有助于你工作的展开。通常,忽略那个嗓门最大的人的声音继续一往无前地改善工作也是办法之一。
如果你终究还是被某些高层人士一致叫停,可能存在两种情况:(a)解决问题的方式有所偏差(可能是你并没有按照我上面推荐的方式去执行,也可能是在和团队的沟通上出现了问题,还有可能是你正在做的事情会对开发者造成负面影响等)。(b)叫停你工作的人愚蠢至极,无论他们看上去多么地“正常”。
如果你的工作被叫停是因为你正在做错误的事情,那么找出什么对开发人员最有帮助,然后回归到正确方向去做就好了。有时候只需要和那位叫停你的高层人士好好沟通就能找到答案。
例如可以暂且把你争强好胜的性格收敛一下,听听他们的意见,评估一下是否有与他们合作的可能性。毕竟和气才能生财。但如果你的工作是被某位愚蠢的人叫停的,并且哪怕有你的支持者为你背书他也无动于衷,那么你或许应该考虑换一个团队了。
没有必要把你的理智和大好心情浪费在这种从不听人劝,还不惜任何代价给你添堵的人身上。另找一个能让你发光发热的地方吧,总比一条路走到黑要强。
想要从容处理工作上的一切障碍光凭这些技巧是不够的,但是相信它已经给了你一些基本入门。比如要持之以恒,要待人和气,找到你的支持者,不要做有损你个人信誉的事情,找一些你能帮得上忙的事情去做。长此以往下去,反对的声音会逐渐式弱,不喜欢变革的人也会悄然离去。
向本质问题前进
假设你现在正在通过渐进的方式,有条不紊地改善团队的开发效率,一些潜在障碍也逐渐被清除。那么接下来该何去何从?答案是请确保你的前进方向瞄准的是本质问题。
总有一天你需要解决这个问题,而解决的方式之一是需要纠正人们编写软件的方式。关于这件事有很多需要知道的,在此之前我聊到过这个问题,在此之后我会再找机会继续聊。如果说无论如何都要对代码进行简化,那应该从什么时候开始呢?通常来说当你遇到一个问题且发现重构才是最好良药的时候,可能会是一个恰当的时机。
先不要对外发布承诺,不要大声宣布你有一揽子改善开发效率的计划,并且计划是从重构代码开始的。如果这么做的话,经理们(或者一部分开发者)会期望你能从中带给他们一些不一样的产出,这些不切实际的要求源自缺乏对你的工作的理解(又或者有时完全出于阻止你的目的,才对你的工作提出不切实际的要求)。你应该等到遇到切实的问题时给出类似的建议:“如果我们能把这部分代码进行重构的话,编写X功能时才会比较轻松。”
自此开始,你要尽可能地提出对代码进行重构。这并不意味着你要停止工具、测试还有流程方面的优化工作。但是你对于重构的坚持,是最能给团队文化带来巨大改善的。你应该希望人们产生一种思维惯性,比如“开发也意味着对代码进行整理”或者是“代码的质量也很重要”。也可以是其他你希望营造的文化氛围。
一旦你在团队内成功建立起了一种改善代码的团队文化,即使你不再对它进行过问,问题也会随着时间推移迎刃而解。这并非意味着工作就此结束了,一旦每个人都关心代码质量、测试和开发效率时,你会发现即使没有你的积极干预,事情也能开始向好的一方面发展,但最坏的情况也不过如此。
请牢记,整个流程的重点并不是在于“达成共识”。你并非在争取团队中每个人关于你应该如何完成你的工作的许可。而是在找到人们认为的问题所在,并且提供一个解决方案将其修复完毕,这个他们认可的解决方案不仅能够建立起大家对你的信任,还能逐步解决代码库的深层问题,并且确保它并不是为了迎合某个人而诞生的。你只需要记住一件事:解决那些人们认为他们面临的问题,而不是你认为他们面临的问题。
最后一件我想要说明的是,所有这些技巧的前提是,你作为个体独自在负责整个公司或者整个团队的效率提升。还存在一些其他的场景——事实上,这并不是大部分效率提升工作的常态。实际工作中有的人会负责一部分工具的研发、有人负责框架的研发、有人负责和下属团队打交道等。
上面提到的“请解决真实存在的问题”这条原则,对其他情况同样适用。上面的大部分内容可能只适用于某一个例子,但最重要的事情依然是,不要解决你认为存在的问题,解决(a)你能够证明存在的问题和(b)开发者们已知的问题。
大部分我曾经共事过的效率提升团队基本上都没有遵守上面的原则,他们花费数年的时间在编写开发者并不需要、也从不使用的工具或者框架,在这些工具开发的团队撤出之后他们便把这些玩意统统删除。时间就这么毫无意义地被浪费掉了!所以请不要浪费你的时间。事半功倍一些,再去改变世界。
——Max