AICon全球人工智能与机器学习技术大会9折特惠中,点击立减¥480! 了解详情
写点什么

技术债管理的七大挑战

2021 年 7 月 14 日

技术债管理的七大挑战

在构建可扩展的软件时,它是最关键的团队。


现实世界中是没有技术债管理团队这样专门修复和解决技术债的团队的。没有人愿意加入这样的队伍。这种团队每天做的事情就是给其他开发人员收拾烂摊子,谁愿意做这种事情呢?


但我们确实有一些名字听起来更专业的团队,比如基础设施团队、架构团队、核心团队,等等——这些名字听起来都很迷人。这种团队负责处理所用应用程序的核心主体,如下图中的核心协调/依赖项小组示例所示。



注意:可以在这篇文章中更深入地了解为什么软件(移动)开发在扩展时需要这样一个小组。


回想一下你刚开始开发的时候,那时完全用不着什么核心团队,因为一个团队就可以搞定所有事情了。然而,随着时间的推移,团队也在不断壮大。我们现在需要更细致地分配工作,让一些团队负责特性交付,一些团队负责公共代码,如下所示。



为了提升可维护性和可扩展性,负责公共代码的团队要探索开发跨各个特性团队的代码,以便重构、改进和更好地对齐。这项工作本质上和管理技术债是一回事。因此,把这个小组叫作技术债管理小组是挺合适的。


不管怎样,本文的重点并不是纠结这个小组的名字——你大可叫它核心、基础设施或架构小组——而是展示这样一个小组面临的各种挑战,并探索对应的解决方案。


在本文中,我将交替使用核心小组、基础设施小组和架构小组这三个名称来描述这样一个小组的挑战。

挑战 1:团队的边界

组建这个核心团队时,团队的边界或范围是什么?


对于某些组织而言,这里是没有边界的。架构团队负责一切事务。他们定义特性团队的所有活动:他们编码的方式、他们实现的类,等等。这样这些活动就会高度一致和对齐了。



但这大大降低了特性团队的灵活性。他们只能做出与架构团队所提供的内容完全一致的东西。如果他们想做一些超出架构团队定义的事情,就需要咨询架构团队。于是架构团队成为了瓶颈。


由于这并不是理想的局面,也许核心小组应该只负责所有现有的通用代码。但是通用代码的定义是非常模糊的。也许这些代码只是一些常见的数据层和实用函数。如果我们将通用代码定义为所有特性小组都使用的代码,那么它只能是全部代码的很小一部分。



这种结构很棒,因为它让每个特性团队都可以自由处理自己的特性,而不会受核心团队阻碍。缺点是(如上图中不同颜色所示)每个特性团队的工作方式会有很大差异。潜在的通用模式、特性和数据可能以不同的方式在各个特性团队中复现,而没人去探索如何将它们抽象为通用内容,因此开发工作的可扩展能力受到了限制。


找到核心团队应该负责的内容的正确边界是一个棘手的难题。它还在很大程度上取决于核心小组的团队能力,以及他们可以承担多少职责。

可行解决方案

组建核心团队的初始阶段肯定很难。我建议从小处入手,定义核心团队可以负责,并为特性小组带来价值的一个重点领域。也许它可以是一些实用函数,等等。


随着时间的推移,核心团队的能力也会提升,它可以接手更多职责。它可以抽象出跨各个特性团队通用的组件,并从那里开始延伸出去。

挑战 2:灵活性与一致性

有时,组织需要让架构小组定义其他所有团队要遵守的标准或规则。这个想法可以追溯到工业化时代,标准化的工厂生产车间更容易扩大规模,浪费也更少。


甚至面向对象编程方法在早期也通过定义基类的能力来推行一致性。基类由核心团队定义,而特性团队只需要实现基类即可。



这种方法有很多收益,特性团队无需自己实现通用代码就可以享受它带来的种种好处。以上面这张简图所示,依赖项 1、2 和 3 都被注入到基类中,这样特性类都可以获得它们而无需额外成本。


为了确保一致性,所有特性团队都不应创建自己的基类。每个新类都必须由架构团队经手。这样做的原因是要避免跨特性团队的意外重复类。如果一个特性团队想要一些新的东西,他们只能与架构团队核对,看看是否已经有了可用的东西。如果没有,架构团队将为他们制作所需的基类。


综上所述,这是一种专制的开发方法,我们可以看到它很难扩展,架构团队成为了瓶颈。此外,架构团队提供的东西可能无法满足每个团队的需求。架构团队可能会疲于奔命,为各个团队构建他们所需的种种变体,或者他们提供的通用类无法被特性团队充分利用。不管哪种情况都是不理想的。


相反,我们可以走向另一个极端:核心团队不定义任何事情。他们只提供通用的实用程序,特性团队可以考虑是否使用它们。


正如最近行业首选的编程方法一样,“人们更喜欢组合而不是继承”,如下所示。



特性团队没有义务遵守基础团队提供的任何规范。对于基础团队提供的内容,他们可以只使用自己需要的东西,甚至什么都不用。特性团队拥有充分的灵活性,可以自由实现他们喜欢的东西。


这种极端方法也有自己的缺点。如果没有对常见实践的一定程度的定义,也没有一致和对齐,各个团队可能走上五花八门的道路。潜在的浪费和重新发明轮子的现象可能会出现在不少团队中。

可行解决方案

我们必须在需要遵守的规范、做哪些“有用的支持实用程序”,以及介于两者间的东西之间取得平衡。


对于必须遵循的规范来说,一个很好的例子是分析需求,我们需要所有特性都有一致的触发方式。


至于“有用的实用程序”,这些工具可以是团队能轻松采用的通用 UI 组件,让他们无需创建新的组件。(一些设计师可能会说这类组件需要完全一致,才能确保整个团队的一致设计风格。)


对于介于两者之间的事物,颜色集就是一个例子。某些颜色需要保持一致,而对于其他颜色,特性团队可以灵活地从一系列预定义颜色中做出选择。


不是每个人都会同意我上面的例子,但你应该能明白我的意思。核心团队需要与所有团队合作,定义什么是必不可少的、什么是灵活的。这不是一个简单的过程。

挑战 3:核心团队的组成

好的,所以我们要组建一个核心/架构/基础设施团队。我们应该让谁加入进来呢?一般来说,也许我们会选择一名专家开发人员和一名初级开发人员组成的组合(假设我们没有太多人可供挑选)。


那么特性团队呢?也许他们的组成与核心团队是相同的。然后每个团队都有相同的团队成员搭配,公平分配。


虽然这听起来很合理,但这样的组成方式可能存在一些挑战。我们必须认识到以下几点。


  1. 核心团队成员实现的是由所有人使用的通用组件,或者要设计与所有组交互的公共抽象。这不是初级开发人员都能应付得来的。同时,我们不能只依靠一位专家开发人员来定义一切。

  2. 核心小组的主要“客户”是特性小组,后者包含一组开发人员,其中还有一些专家。同样,初级开发人员没有足够的能力来同更有经验的“客户”联络并做出可靠和有意义的东西。只靠核心组中的一位专家开发人员来应付所有特性组也是不够的。



鉴于这种情况,也许我们需要在核心小组中配置所有专家开发人员。这要好得多,因为我们在与特性小组合作时就能应对可扩展性的挑战。但是,把所有专家都放在一个团队里的话,为这个团队定义方向时可能就会遇到麻烦了。或许我们可以在专家中找出一位领导,让他来确定方向。


另一个挑战是让核心团队支持多少个特性团队。如果后者的数量太多,我们如何扩展核心团队来提供最出色的交互和支持?

可行解决方案

在我看来,如果我们想要建立一个稳固的核心团队,团队中肯定需要配置更多经验丰富的高级开发人员。这个团队要定义和开发大部分核心内容,或者可能是所有人都使用的架构,因此它的工作需要在技术上足够稳固和可靠。


最重要的是,如果可以的话,我们应该在每个特性团队中都配置一名来自核心团队的大使(下图特性组中的绿色人员),这会是很有价值的。在组织结构上,他们可以是特性团队的成员,但他们在实践中会积极参与决策以及核心团队产品的开发。



他们在特性团队中还能充当监督者,确保在特性开发过程中进行必要的调整,并持续定义核心团队可以扩展的领域。同样,这位大使还需要足够的技术经验才能担任这样的角色。


这样一来,核心小组的领导者就需要能够管理一组专家开发人员,不仅包括核心小组内的专家,也包括各个特性组中的大使角色。

挑战 4:产品和利益相关者管理

对于一个产品来说,通常我们有一个产品经理来监督工作,判断各种特性需要哪些改进。他们与利益相关者沟通,并不断与客户群互动,找出接下来最佳的工作方向。



某个特性的开发人员从产品经理那里获得单一输入源,获知下一步的开发方向和优先级。开发人员不需要与利益相关者打交道。他们的工作重心都放在开发上。


核心小组不再直接处理外部使用的特性。他们不面对外部客户。这里没有真正的“产品”,也不需要团队的“产品”经理。


但核心团队确实有自己的利益相关者,他们就是各个特性团队。核心团队需要与一组开发人员保持联系,后者进行各个特性的开发工作,并交付有意义的成果。



与各个特性小组中的开发人员联络、讨论具体需求以及对各个需求的优先级做出妥协等过程,需要特定的产品和利益相关者管理技能。


一般来说,开发人员不具备此类技能。如果没有合适的产品和利益相关者管理方法,小组就无法确定自己的工作方向和重点,因为每个特性组的需求可能截然不同。

可行解决方案

在理想的世界中,这样的小组会有一名技术产品经理,他既精通技术,又精通产品和利益相关者的管理工作。担任这一职位的人也可以是小组的技术负责人,他为小组提供指导。他必须有足够的时间来工作,并与其他特性团队联络,还必须牺牲自己的时间来专注于技术工作。这是一个艰难的角色,因为他在完成其他任务的同时还不能让自己的技术能力退步。


或者另一种选择是让一位首席开发人员或架构师负责监督核心团队,并对各个特性团队产生影响。处于这种位置的成员可以设定产品的重点和方向,以确保整个产品高层次上的优先级得到合理安排。核心团队的各位成员(具有一定专业知识水平)可以与各个特性团队一起确定更细节的工作内容。


不管怎样,利益相关者管理是确保核心团队成功所需的技能,这种技能并非单纯的技术知识。

挑战 5:工作结果的可见性

我记得当我参与一个软件特性的开发工作时,看到那个特性发布时我真是太高兴了。我开发的软件是由普罗大众使用的。因此,当我看到自己的朋友也在使用那款软件时,我就可以告诉他们那是我开发的——多么有成就感啊。


或者当有人问我做的是什么工作时,我很容易向他们展示自己的产品,告诉他们并让他们了解我的工作。当一个软件特性的新版本发布时,我可以让他们去体验一下。每次版本发布后,我们一般都会切蛋糕来庆祝一番。


但是人们在基础设施团队工作时,这里没有任何能让外部用户轻易看到的有形特征。他们完成的工作可能只是又一个 API,或现有服务的一个新属性——这种成果远不足以发什么公告,看公告的用户看到这么点东西会很生气的。但没有公告,他们所做的工作就不会被别人注意到了。


有时,核心开发人员会改进核心库,让代码更容易维护,或者做一些轻微的性能改进(例如减少内存占用)。这样的工作不会改动哪个接口。使用核心库的人们甚至都感觉不到。没有人注意到或欣赏这些成果。


有时候,核心库会迎来新版本的发布,但发布公告看上去也就是那么回事。如果新版的改进没有给特性团队带来太多价值,后者可能就不会那么欣赏它。相反,特性团队可能会讨厌这样的公告和更改,因为他们必须多做一些事情才能使用新版库,或做一些更改才能适应新的接口。


相比之下,如果核心团队成员编写的代码导致核心库的质量下降或影响了特性团队,那么使用这些代码的人们可能很快就会注意到了。不开心的“客户”可能会“升级”问题。


这样的环境对团队所做的工作评价很低,对他们犯的错误惩罚却很高,于是核心团队中的开发人员很快就会士气低落,没有人愿意呆在这样的团队里面。这个团队现在实际上就是技术债管理团队了:高风险、低收益。没有人愿意加入这样的一个群体。

可行解决方案

也许核心团队也应该像特性团队一样对待他们的工作。每次迭代都应该有要达到的里程碑。计划中的内容(例如他们可以为特性团队或整个产品带来的价值)应该提前让大家知道,这样大家就有了对新版本的期待。


核心团队的领导需要与特性团队协商制定高层计划。领导还要跟踪自己的团队过去取得的所有成就。所有重大里程碑都需要庆祝一番。团队的优秀作品需要广泛传播和分享。


关键在于让核心团队成员感受到他们的成果是被他人看到和欣赏的。毕竟,我们去工作不只是为了钱,也是为了成就感。

挑战 6:成功的衡量标准

在学术界,已经有了很多衡量产品成功的研究。有很多分析工作会探索软件特性的使用情况,以及它如何转化为组织的底线。


开发人员衡量一个特性是否成功时,部分标准包括能否及时向用户交付特性,以及特性的质量(例如崩溃率、资源利用率、性能)。


但对于核心小组来说,如何衡量他们的成功呢?他们没有有形的、面向客户输出的产品。当然,我们可以说我们提供了这个库、那个 API 服务,等等,但这样做有什么意义呢?拿组织底线来说,核心团队如何为组织的潜在成功做出贡献?

可行解决方案

评价核心团队成果的一种方式是,把它看作是为公司提供所有所需计算机和基础设施的 IT 部门那样。它就像一个对支出做出重大贡献的部门。


一般情况下,管理层希望尽可能优化这样的部门的成本,除非这个部门能够证明其贡献,证明他们是如何提高所有人的生产力的。


因此,如果我们有一种方法来衡量特性小组获得的生产力或开发扩展能力,那肯定是非常有价值的。也许一种简单的方法是统计特性团队使用了多少 API,当然这个例子太简单了。这里没有一目了然的公式,说起来容易做起来难。


也许第一个衡量标准是特性团队对核心团队提供的支持的感受。如果所有特性团队都感受到了核心团队的价值,那至少是一个很好的开始。


沿着这些思路,有几个行业案例展示了这样一个核心或基础设施团队的巨大成就。一个例子是 AWS,它的服务器最初只是在亚马逊内部提供服务,现在已经成为亚马逊最大的业务部门。


像 Airbnb 和 Square 这样的公司也是类似的例子,他们开发了很多核心库供其他开发人员使用,这对组织在开发社区中的声誉做出了重大贡献。虽然这些工作没有直接的收入收益,但组织因为这些成果而更容易招纳人才了。

挑战 7:不断变化的软件技术

软件开发是变化最快的行业之一,甚至可能是变化最快的。业内每年都会推出一些新的东西。有些变化是渐进的,有些是革命性的。


一般来说,核心基础架构团队或架构团队负责定义特性团队应该采用什么技术框架来确保一致性。


这也意味着随着软件技术的不断变化,核心团队感到自己有义务站在曲线的顶端,并能够正确识别出下一个要采用的最佳技术选项,然后朝着这个方向努力。


这也是我之前建议核心团队应该由一群非常了解并密切关注技术趋势的专家组成的原因之一。


虽然理想情况下核心团队可以推动这一进程,但它不是一个可扩展的解决方案,因为核心团队的开发人员只占全体开发人员的一小部分。

可行解决方案

应对和探索最新技术趋势的责任不应该只由核心团队来承担。每个小组的开发人员都应该对新事物充满热情。此外,如果我们不让其他小组的开发人员成为探索某些新技术的先行者,我们也是在打压他们。


虽然核心团队有责任向所有人部署最新技术,但每个团队(包括特性团队)都应该有试验新事物并提出建议的自由。


这种自由很棒,因为它可以跨团队进行可扩展的探索活动。并非所有新学到的技术都应该被采用。从特性团队中吸取的教训可以帮助组织过滤掉不适合的技术。那些表现很出色的技术可以推荐给核心团队,后者可以考虑让其他团队也采用它。



当然,出现相互矛盾的技术时,核心团队是仲裁者并决定哪个应该优先采用。

总结

技术债管理团队是组织希望扩展产品开发工作时必不可少的重要团队。我们可以将其命名为核心团队、基础设施团队、架构团队,甚至像 SWAT Team 这样有趣的名称。


为了确保可扩展性,核心团队需要在强制的一致性和放松的灵活性之间做出平衡,对特性团队提供适当的支持。这种错综复杂的平衡只能与特性团队之间紧密协作才能实现,这需要团队具备稳定出色的技术能力,同时还要妥善管理利益相关者事宜。


虽然核心团队可能没有任何直接、有形、面向客户的外部输出,但它的贡献对整个产品开发工作的成功都非常关键,所以应该是可见的。如果我们能够量化它的工作,那将进一步确保团队的贡献可以持久,并提升团队的士气。


确保产品技术健康水平的责任不应仅仅由核心团队承担。所有团队在产品的技术进步过程中都扮演着重要的角色。核心团队负责仲裁和促进流程,确认所有团队的重点方向。


组建这样一个核心技术债管理团队并不容易,维持和扩展它是更难的事情。但是,如果我们真的想扩大我们的开发规模,这样的团队是必不可少的。


原文链接:


https://betterprogramming.pub/the-7-struggles-of-a-tech-debt-management-team-ec8ef8316369

2021 年 7 月 14 日 14:345082
用户头像
刘燕 InfoQ记者

发布了 647 篇内容, 共 203.4 次阅读, 收获喜欢 1245 次。

关注

评论 1 条评论

发布
用户头像
很好的思路,很多点不谋而合,然而对于中心化的管理思维不认同。团队自治才是理想状态,也必须是自治才能有效。需要做的是负债管理的方法论的沉淀与长期持续培训。
2021 年 07 月 19 日 11:32
回复
没有更多了
发现更多内容

浮点数比较的精度问题

C语言与CPP编程

c c++

欢迎观看 AzureShow

亮小猪

云计算 开源 技术社区 azure 视频

《我要进大厂》之mysql夺命连环13问

艾小仙

Java MySQL 面试题 Java 分布式 大厂

AtmoicXXX与AtmoicXXXArray源码分析

Darren

源码 内存布局 CAS java 并发 AtmoicXXX

Docker 安装和简单使用

枫林

Docker

最通俗易懂的 Redis 架构模式详解

哈喽沃德先生

redis 架构模式 redis集群 redis哨兵 redis主从

在Alibaba广受喜爱的“Java突击宝典”简直太牛了

Java成神之路

Java 阿里巴巴 程序员 面试 架构师

Docker -快速安装Elasticsearch

枫林

Flink检查点存在的性能影响-16

小知识点

scala 大数据 flink

你真的了解 Base64 吗

hepingfly

Java base64 编码

甲方日常 7

句子

工作 随笔杂谈 日常

oeasy教您玩转linux010203显示logo

o

联盟:互联网时代的人才变革

非著名程序员

互联网 个人成长 人才 人才发展 突破圈层,个体崛起

关于MySQL参数,这些你要知道

Simon

MySQL 参数

架构师训练营0期 第十二周作业

WW

C语言与C++常见面试题

C语言与CPP编程

c++ 面试题 C语言

Elasticsearch初步认识

枫林

Java elasticsearch ES

mPaas 厂商push不通排查指南

阿里云金融线TAM SRE专家服务团队

android push

话题讨论 | 你的桌面上会放哪些有趣的小摆件?

InfoQ写作平台官方

工作 话题讨论 办公室

百度被绿了?

程序员生活志

百度 互联网 头条

再爆安全漏洞,这次轮到Jackson了,竟由阿里云上报

YourBatman

Jackson Fastjson 安全漏洞 CVE-2020-24616

我们一起学程序-五子棋

叫练

Java 多线程 游戏 websocket

深挖 Redis 6.0 源码—— SDS

yanglbme

redis 源码 源码分析

终端传感了解吗?18个知识点为你扫盲

华为云开发者社区

IoT 信息化 传感器 传输协议 无线传输器

面试官问:Spring Boot中Tomcat是怎么启动的

Java小咖秀

tomcat 面试 springboot

指针变量的传值和传址

C语言与CPP编程

c++ 指针 C语言

闲聊胡扯

C语言与CPP编程

随笔杂谈

Java集合源码学习笔记,Java程序员面试必备基础知识

Java成神之路

Java 程序员 面试 集合 架构师

微服务下数据一致性的几种实现方式

xcbeyond

微服务 BASE理论 数据一致性

Pod安装神策SDK报错Remote branch v2.1.3 not found in upstream origin

凌宇之蓝

ios 小程序flutter, 跨平台 CocoaPods pod React Native

你真的懂AQS吗?透彻理解AQS源码分析系列之AQS基础一

InfoQ_d2212957090d

AQS

新晋管理者都会遇到的6个问题

新晋管理者都会遇到的6个问题

技术债管理的七大挑战-InfoQ