我有一种感觉,当人们看到软件的经济潜力后,就会开始寻找 “扩大规模 ”的方法,不止不休。
软件有一些奇特的地方,使它与其他事物不同。很久以前,我读过弗雷德里克·布鲁克斯(Frederick Brooks)的《神话人月》,书中提到了一个概念交“意外的复杂性”(accidental complexity)。为什么我们已经找到了许多创造性学科组织工作的方法,但写软件仍然很难?
我说软件很难是什么意思?自己写软件也许需要花几天时间去做,工作中,变成了企业跨越几个月或几年的项目,这还只是创业公司,可能只有50个软件工程师。大企业中还有更糟糕的情况。
某公司一位很资深的管理者曾对我说,所有的大公司都是“这样”运作的,大公司 “能成功”。我说的 “这样”是指中央项目管理,迁移项目需要几个月才能完成,而对客户的影响却不明显。就像是拿破仑在一些山上排兵布阵。他需要把骑兵放在前面,但首先他要把这支部队调到河对岸,但在这之前,还需要把另外三支部队调来调去等等。当然,这可以做到(就像Twitter臭名昭著的放弃Ruby on Rails,改用 Java一样),但这并不好玩,也没有很好地利用大家的时间和金钱。
有趣的是,我突然就联想到军队,这可能就是大脑的工作方式吧,还有许多其他比喻 “规模化 "地编写软件的意向:比如瀑布,一种自上而下的方法,它的灵感来自于工程项目。布鲁克斯提出的是外科医生的团队作为更好的隐喻。敏捷软件开发没有明确的隐喻,除了本质上是一群人之外(”人高于流程!“)。以及,不要问我SAFe(大规模敏捷开发)像什么!
我发现自己又想到了电影行业,因为这也是一项既具有高度创造性,又有很多专业性的活动(有谁真的知道 “best boy grip”(第一灯光助理)是干什么的?他们也花了几十年的时间来摸索,所以也许这就是软件开发所缺少的。
那么,软件开发有什么特别之处呢?它似乎是一种在一心一意的情况下受益匪浅的活动。然而,你面前的代码只是冰山一角,似乎即使做的很好,你有时也需要把它全部换掉,重写一遍(当然,如果你必须这样做,至少要快)。
一旦涉及到不止一个人,你可以尝试让他们都在同一个心理表征上工作,就像在结对编程(pair programming,两个程序员一起配合)中一样,或者你需要引入一些责任区域,让每个人都能管好自己的事,或者至少更独立地工作。
我很久以前读过的另一本书叫《形式的合成笔记》( Notes on the Synthesis of Form),作者是Christopher Alexander,如果我没记错的话,其中一个主要的观点是,每当你需要针对许多约束条件设计一个系统时,如果你一次解决一个单个的问题,事情就会成倍地变得简单(当然我是这么解读的)。所以这是个好主意,对吧?
问题是,把问题分解成几个部分,就严重限制了解决问题的空间。如果你做错了,正确的解决方案取决于两个不同的部分,如果孤立地看,可能找不到解决方案。
对于某些类型的程序(如webservices),我们找到了如何架构它们以使工作更容易的方法,但往往当你在编写那一个将为你的创业提供动力,并使你进入十角兽(创业不到10年但市值超过百亿美元的科技公司)领域的软件系统时,你可能只在半途才弄清楚什么是最好的方法,如果你没有勇气去清理这些东西,你最终会得到一个没有监督就无法工作的分工,这意味着需要软件架构师、项目经历和频繁的检查。
这种工作分离的情况,在你决定谁在一个团队中从事什么工作的时候,每次都会发生。一旦你在公司中定义了团队,也会发生这种情况。这将对你所写的软件产生非常真实的影响,也就是所谓的康威定律( 大致意思是设计系统的企业,它们生产的设计等同于企业内的沟通结构)。Skelton和Pais写的《团队拓扑结构》(Team Topologies)一书就采用了这种见解,并应用了 “反向康威手法”,按照你希望系统的样子来设计团队。但你还是需要知道你的系统应该是怎样的。
敏捷软件开发提出了一个强有力的策略,那就是写最简单的能用的东西,然后不断重构(就是提纯的意思)你的代码库。有一些书(很久以前读过的一本Martin Fowler写的 "Refactoring")谈到了重构,但这些大多是一些较小的改动,比如把类中的字段移到它们所属的地方(此处为简化说法!)。
在这一点上,已经非常清楚,“规模化地编写软件”不是一个努力或意志的问题。单纯的 “快速行动,打破局面”是无法帮助你实现这个目标的(是的,我知道他们把它改成了 “用稳定的基础设施快速行动")。我们架构软件和团队的方式是非常现实的,会制约任何一个工程师或团队能做什么、要投入多少工作。
我发现自己又回到了城市的比喻,我第一次读到这个比喻是在格雷和范德沃尔的《连系公司》(Connected Company)一书中。城市之所以引人注目,是因为城市往往相当古老,几乎看起来是不朽的,即使它们在数百年或数十年间被重建和改造,并不断变化。
城市是人类活动的平台。它们提供了基本的基础设施,如道路、电力、建筑、你可以租用的商店空间,现在还有互联网。其中一些基础设施的变化非常缓慢(如道路),而另一些基础设施的变化则要灵活得多,如公寓或商店的用途。
如果也用同样的方式构建软件呢?如果我们企业的核心部分像街道一样,新的东西都是我们可以在上面搭建、实验,不行就拆掉的东西呢?我从内部看了几家电商公司,虽然他们的系统是能够每秒处理上千笔交易的技术奇迹,但感觉并不是这样,而是像App和网站这样的东西和其他的东西纠缠得很深。即使你想,你也无法创建一个100%全新的应用或网站。
反过来说,如果我们用建造软件的方式来建造城市,你可能就需要从专门的车库进入店铺,从屋顶出来走一条电线,才能到另一个用废旧集装箱定制的建筑去结账。而有些窗户是涂上去的,因他们是MVP(最小可行性产品)。
我们正试图通过平台团队来实现,就像城市里的电力公司一样,提供商品服务,这样就不需要每个人都在地下室里运行自己的柴油发电机,这是一个很好的第一步。但往往平台团队要迎合太多不相干的 “客户”(比如后端服务和数据科学家都要部署基础设施),我们通过强制使用平台团队来消除激励,使其为客户做好服务。
城市也很了不起,因为只有有限的中央控制。如果有市场,商店就会开张,如果没有足够的生意,商店就会关闭。相比之下,大多数公司的经营方式更多的是自上而下,导致做出错误或不正确的决定。
至少,在公司内部建立一个新的项目,应该比从零开始更容易,但我的直觉是,很多公司都没有通过这个测试。
你现在可能已经意识到了,我只有指针,没有答案。我们仍然没有做到这一点。也许在50年后,我们已经找到了正确的角色,正确的团队结构方式,以及正确的方法来架构软件 “城市”,这些城市是有趣的。
在此之前,我的建议是审视一下结构,问问自己,在你的 “系统”中,任何一个 “单元”完成事情有多难,一切跨责任区的事情都会增加复杂性。《团队拓扑学》(Team Topologies )一书建议,要偏向于端到端的团队,完全负责一个要解决的问题,由平台团队管理一个非常复杂的技术的团队来进行支持。
对于那些需要以流水线方式进行协作的团队来说,无论如何都要从整个系统中找出瓶颈,并集中精力加以改进。这就是Eliyahu Goldratt的 “约束理论”的核心思想。你需要限制正在进行的工作,使其与你的瓶颈相匹配,其他的都是瞎忙活。
也许还有另一种方法,研究如何让人们更有效地合作。我在上面简单地提到了结对编程,我不得不承认,我历来认为这是做不到的,或者说只有少数非常了解对方的人才行,并且已经想出了一种方法,可以互相启发。
具有讽刺意味的是,根据我的经验,仅仅是互相交换想法并不是种好方法。你可能最终的结果是,人们把自己的想法扔进圈里,只是为了让别人发现其中的错误。在最坏的情况下,这可能会变成一场比谁最懂、谁最聪明的比赛。
除非你注意每个人对问题的理解不同,没有注重信息收集和建设性的创意。我最近开始阅读更多的设计思维方法,比如说,利用头脑风暴既收集信息又产生新的想法。我发现这些东西对共同解决问题有惊人的效果。无论如何,我们肯定还没有搞清楚如何规模化地编写软件的方法。
CIO之家 www.ciozj.com 公众号:imciow