管理

垫片,夹具和其他木工概念征服技术债务

在90年代早期,著名的计算机程序员和维基百科的发明者沃德·坎宁安首先综合了复杂技术开发和债务的概念.这个新创造的术语为困扰着世界各地的开发团队的一种沮丧感提供了一个名称。他警告说,工程组织在发布的每一行有效但不完美的代码中都积累了增量债务。如果能及时用重写来回报,那就再好不过了。但如果不这样做,债务的利息会对拥有它的工程团队产生影响,导致其崩溃。

输入一个医疗集团首席技术官金柏洛克哈特在工程学上,它相当于你精明的财务规划师。洛克哈特信奉一种哲学——灵感来自木工——帮助初创公司明智地控制技术债务的产生和积累。在担任现任职位之前,她在Box的四年任期内迅速晋升。在Box,她从软件工程师起步,逐渐成长为应用程序团队的领导者。她加入了盒子收购云存储后启动文档共享Increo她是该公司的联合创始人和领导。

在这次独家采访中,洛克哈特解构了技术债务,并提供了木工技术,将更好地帮助您管理它。就像其他精明的技术头脑在权衡利弊,她分享了如何巧妙地走捷径,特别是在工程环境中,速度和完整性的需求可能是最重要的。

技术债务不是红字。最优秀的团队都会遇到这种情况。我认为创业公司没有任何技术债务是不负责任的。

如何在技术债务变成坏代码之前处理它

关于债务——技术性或其他方面——的污名是,它是软弱的标志,或导致过度依赖,而实际上,它只是代表了一种权衡,以付出更多的时间或资源为代价。“即使是表现最好的团队也会产生技术债务。不同的是,他们这样做是为了走捷径。走捷径通常是不好的,但有时可以在一个不断发展的企业中做出深思熟虑的选择。当使用太多的捷径来节省时间和技术债务时,就会产生糟糕的代码。关键是要敏锐地理解企业成长过程中各种捷径的权衡,”洛克哈特说。

例如,如果你的目标是实现适合企业的产品市场,你的首要任务是快速迭代,以确定你是否以适合企业的速度为合适的用户开发了合适的产品。洛克哈特说:“在这种情况下,通过走捷径来假设技术债务可能是值得的,即使这会引入糟糕的代码。”“这不是给坏代码开空头支票,但它有微妙的用途,以便在短期内赢得胜利,以确保长期。这就是技术债务的双重优势。”

简而言之,技术债务本身并不是坏事,但其管理方式决定了其对企业的正面或负面影响。以下是洛克哈特关于如何谨慎使用技术债务的建议:

混合木匠大师.洛克哈特说:“年轻的创始人——实际上是所有的团队领导——通常会雇佣太多经验刚刚起步的工程师。”“防止技术债务产生糟糕代码的一个简单方法是,让有经验的人组成绿色技术团队,他们可以利用过去的经验更熟练地做出困难的决定。”

在One Medical和Box,洛克哈特都认识到依靠经验丰富、技术经验丰富的工程师的价值而且对积累和解决科技债务做出合理的判断。“他们需要看到自己亲手打造的东西推动企业向前发展,他们需要为自己走了一条捷径而后悔。这是一个耗时的过程,但除了亲身体验,没有别的选择。

所以,创业者们,不要局限于自己的社交圈。寻找那些在公司工作足够长的工程师,以体验他们的决定所带来的长期影响。年轻的开发者们,有几双经验丰富的眼睛。兽医们,带上环保工程师。洛克哈特说:“拥有更多的视角是利用人们积累经验和解决技术债务的关键。”

三思而后行.开始代码评审之前任何代码最好的技术团队会一起设想——而不仅仅是审查——代码。“毫无疑问,某种形式的代码审查在任何类型的工程组织中都是必不可少的,”Lockhart说。“在早期,结对开发或坐在一起阅读代码是可行的。随着团队的成长,从不同的个人或团队获得更正式的代码评审可能是很重要的。”

洛克哈特说:“对于许多公司来说,流程的发展使得代码评审成为工程师获得代码反馈并不断迭代使之变得更好的唯一机会。”“不幸的是,事后发现问题迫使我们不得不在花时间重写和忍受糟糕的代码之间做出艰难的决定。”

提前进行更多的讨论并不意味着要执行一个艰巨的计划过程。“一开始,把所有人聚集在一块白板周围,拍张照片分享。可以很随意,”洛克哈特说。重要的是让多人参与讨论并写下结果。你想要的并不是一份冗长且正式的设计文件,而是挖掘团队的智慧并采取最实际的行动。”

一个医疗首席技术官金柏·洛克哈特

收集和编纂您的标准。起初,木工技术主要是通过个人相传的。随着行业的专业化和创作变得更加复杂,木工制作了指南和模板书。与他的论文当时,罗马建筑师和作家马卡斯维特鲁威产生了最重要的,最原始的规划和设计来源之一,标准化了如何建造小型测量设备的渡槽。

“这很简单,但很多团队并没有这么做。在编程中有多种有效的方法来完成任何事情,而最糟糕的选择就是不一致地选择,”Lockhart说。更好的做法是,把你的标准写成剥绒机或其他静态分析器.从一组几乎为空的规则开始,然后随着您对代码的标准达成一致,慢慢添加规则。是的,让你的代码符合每条新规则需要花费一些时间,但一致性将有助于防止糟糕的代码。”

放弃那些不能节省时间的捷径。木工知道什么时候可以走捷径,什么时候不走捷径。要重新涂饰木材,现有的涂饰必须完全从木材上剥离——不需要擦拭聚氨酯就够了。采取不移除现有表面的捷径最终所花费的时间和正确的方法一样长,特别是当新的表面覆盖在旧表面上,干燥后,你必须修复潜在的缺陷。

同样,洛克哈特发现,捷径也可能是一种幻觉——通常编写干净的代码所花费的时间与生成引入技术债务的代码所花费的时间相同。“问题是,糟糕的代码通常感觉更快,就像匆忙的感觉更快一样,”Lockhart说,“很少有时间浪费在规划上,代码本身也会更疯狂地编写。”

“选择无效捷径通常不是由于手头的任务,而是由于任务周围的环境。如果你的团队缺乏经验,或者承受着很多不必要的压力,人们往往会选择不那么理想的方式来构建一些不节省时间、精力或资源的东西。”“我在Box的第一个项目是将我的第一家公司Increo的文档预览技术集成到Box产品中。我给自己施加了很大的压力,要求自己快速完成集成,并在适当的地方重用一些代码模式,而不是用新的眼光来思考问题。虽然我的方法看起来像是一种捷径,但事后看来,一种更简单的方法可能会带来更直观的实现,从而更快地完成游戏。”

洛克哈特建议:“领导者可以通过招聘有经验的人、实现早期设计和代码审查以及避免不必要的时间压力来抵消这种趋势。”

构建到模块化。对于那些快速制作、拆卸和重建的家具,木匠会使用可拆卸的紧固件,一种允许快速拆卸和组装模块化部件的连接类型。它们促进了灵活性和容易完成,即使是新手。同样,模块化代码也很灵活,在模块内实现复杂的更改比跨大型代码库更容易。

对于工程团队来说,未完成的框架转换是导致技术债务混乱的最常见原因之一。随着今天前端web框架的扩散和开源工具的快速版本化,使用最新和最好的工具的诱惑很大。在转换之前,Lockhart建议考虑一下:“为了从新框架中获得的功能的略微提高,值得重写代码吗?”

“通过尽可能模块化地构建代码,您可以使这个等式看起来更好,”Lockhart说,“用特性和功能之间的断线分割这些模块。然后,应用一个新框架的成本只是重写一部分代码的成本。”

“在One Medical,我们有一个中央API和数据存储,但不同的应用程序将这些数据呈现给不同的受众。每个小应用程序都可以运行核心框架的略微不同版本。这样,当你只想为一个用户做出改变时,你就不必在整个组织中做出改变。”

当你面对糟糕的代码时该怎么做

技术债务应该是一个采取捷径的可控决策。当出现太多不协调的快捷方式,技术债务被“透支”时,就会产生糟糕的代码。以下是如何区分优先级,标签和导航由持续的技术债务产生的糟糕代码。

为糟糕的代码创建一个评级系统。洛克哈特指出:“许多工程团队哀叹他们的组织未能充分解决技术债务导致的糟糕代码,但当被问及如何解决时,他们却无法站稳脚跟。”“工程团队应该仔细地确定组织的优先级,就像其他人提出请求一样。”

在Box的团队中,Lockhart设计并使用了一个系统来对这类糟糕的代码进行评级和排序。为了获得评级,团队会考虑三个不同的因素:

安全.这些糟糕的代码是否存在安全问题?

患病率.糟糕的代码有多普遍?它与代码库的不同部分如何交织在一起?

频率.您经常接触到糟糕的代码吗?当用户与产品交互时,它多久运行一次?

洛克哈特说:“在对这三个因素进行评级之后,就会对项目进行一个粗略的排名。”但是,没有一个评级系统是万无一失的,没有人扫描来确保优先级合理。自动记分卡不能记录一切。”仔细地确定项目的优先级以解决糟糕的代码就像先偿还高利率的信用卡一样——它可以防止债务复利。

技术债务就像毒橡树。它是自然流行的,但不需要被删除以避免。一个警示标志会有很大的作用。

封装并标记糟糕的代码。工程团队可能会感到压力,要么继续开发糟糕的代码,要么立即发现并删除它。然而,中间还有一个阶段是有用的,不那么激进,也不那么耗时的。“如果你的代码中有一部分是不好的,你不希望人们重复它,就给它贴上标签。通过这种行为,您可以明确地指出哪些代码不应该再遵循,即使它目前对于功能来说是必要的。”它可以很简单,比如不赞成某个函数,或者插入一条注释,指出代码不再符合开发团队的现代风格。这将有助于防止不良代码的传播。”

“下一步是包含不良代码,这样它就不会传播,”洛克哈特说。“一个简单的例子可能是隔离对象上的错误代码,并用整洁、干净的新功能扩展该对象。”

“你在森林里会比在书里找到更多的东西。树木和石头会教你那些你从大师那里学不到的东西。——圣伯纳德·德克莱尔沃

构建工具来对抗坏代码.为了处理和消除负技术债务,洛哈特借鉴了两种木工工具和技术垫片跳汰机.垫片是一种薄的、锥形的楔子,用来填充物体之间的小间隙,而夹具是控制另一个工具的位置或移动的辅助工具。以下是Lockhart如何将这些工具应用于软件开发:

的垫片

在木工中,垫片的目的是为了更好的定位。“垫片通常是一小块木头,当两个部分不能按应有的方式连接在一起时就插入。有时它会留在最终产品中以确保更好的结构,但它也可以在发挥作用后被移除,”洛克哈特说。“Shimming code是将一些代码放在一起,让两个部分一起工作的概念。所以,如果你的代码中有一部分没有显示正确的界面,你可以添加一个层,让它按照你的要求去做。”

一个垫片

在One Medical, Lockhart和她的团队试图扩展其消息服务的功能。“我们计划建立这个模块,使医生和病人之间的消息传递变得容易。问题是,我们最初构建代码是为了发送不同类型的消息,”洛克哈特说。“我们担心我们需要从头开始,重写整个系统来接受新类型的消息。相反,我们编写并插入了一个垫片,以便旧系统能够接受新类型的消息。我们避免了花费数月时间重写旧代码。”

一个常见的垫片的例子是软件开发工具包(SDK),开发人员可以生成它,以便更容易地使用来自客户使用的语言的API。“这是一个垫片,因为它是一层薄薄的代码,消除了断开,”洛克哈特说。

“我最喜欢的shimming代码用例是API版本控制.随着公司的发展和迭代,api的变化是很常见的。为了保持旧的集成工作,公司经常选择对他们的API进行版本调整。API实现的v1不可避免地存在大量技术债务,代码也很糟糕。这里的机会是构建API的v2,然后使用一个shim到v2的v1接口的实现,删除旧的代码,并允许API一致工作。

洛克哈特认识到,大多数工程师可能不认为这种技术是一种垫片。“优秀的工程师总是这样做。但通过给这个工具命名,我们注意到我们认为它是一个更可接受的选择,”她说。“比起完全重写它,我们现在可以在内部说:‘嘿,你确定我们不能用垫片做到这一点吗?’它具有认知度,人们更频繁地将其视为自己工具集中的一种工具。”

洛克哈特对垫片提出了警告,“像任何捷径一样,对垫片的过度依赖会导致技术债务和糟糕的代码。确保你使用垫片来完成最后一英里,而不是做重物搬运或大的拼接。”

需要立即解决技术债务的想法在公司的所有阶段都不是一个有用的心态。

的夹具

“夹具比垫片更复杂,它是一种由木工制作的工具,它促进了最终产品的制作,但并不会进入最终产品。例如,它可以是一个引导锯子实现复杂切割的设备,”洛克哈特说。“夹具通常不会很快生产出来——进入夹具的工艺和最终产品一样多。通过避免在夹具上走捷径,你最终会得到一个更好的成品。我曾经很讨厌在任何不是最终产品的东西上努力工作。但在快步舞上的投资是完全值得的。”

一个夹具

应用于技术,夹具是任何以实现更好的代码为主要目的的代码,而不是交付到生产中并自己使用。在清理坏代码的过程中,夹具特别有用,可以提供支持。

在这个意义上,最明显的夹具的例子是测试自动化。编写测试代码来练习应用程序,以确保它按预期工作。测试代码不是最终产品的一部分,但它使产品更好。测试是避免坏代码的最重要手段,每个新特性都应该测试,每个bug修复都应该包含一个新的测试,以防止出现问题。甚至编写你打算丢弃的测试代码也是有价值的——有时,安全修改旧代码的唯一方法是为它编写测试,重写代码,然后删除初步测试,以便在新代码上进行更可靠的测试。”

夹具也存在于测试之外。“比方说,我正在编写一个API,通过一个web应用程序向某人发送一条文本消息。为了彻底测试该API,我可能决定生成一个非常简单的客户机来使用我所编写的API。最终我将抛弃这段代码——它的存在只是为了让我能够创造出更好的API。”

组件库或生活风格指南是另一个jig的例子,它帮助测试和维护前端组件。“在编写面向客户的代码时,使用组件编程是一个很好的实践,而不是从头开始。开发人员不是一次又一次地构建一个按钮,而是构建一个按钮并在任何地方重用它。这是现代开发人员思考如何编写用户界面代码的重要部分,”Lockhart说。“Twitter的Bootstrap库就是一个很好的例子。您可以看到每个组件,因此如果有人试图修改组件,那么很容易通过转到库页面(用户永远不会看到的页面)看到意想不到的副作用。这样做的好处是,您可以隔离组件,对它们进行更改并评估影响。这些都是昂贵的工具,但通过投资这些时间,您可以为用户节省数小时的错误修复和错误部署时间。”

关于垫片和夹具的选择

像大多数工匠一样,开发人员也有他们最喜欢的工具。“当公司减少生产,开始更多地迭代以达到产品市场契合度时,在垫片上加倍投入是明智的。有了它们,你可以快速行动,而不会产生大量的技术债务。”“jigg在早期是比较困难的——很难去考虑你会丢弃的建筑代码。但如果你的目标是创造高质量的内容,这便是一个强大的理念。

几乎你产品的每一个元素都需要在未来的某个时候重新访问。由于技术债务而无法做到这一点会让人瘫痪。

技术债务可能是快速增长的公司的信号,也可能是它们的压力。我们的目标是监控和管理技术债务,并采用一些策略,如给技术债务贴标签、创建评级系统和以模块化的方式构建代码。使用诸如垫片和夹具等木工技术不仅可以减轻技术债务,还可以帮助您的工程组织更快、更聪明、更协作地发展。最后,当您培训您的工程团队时,请那些经历过技术债务的完整周期的老手加入其中,这样您就可以奖励他们采取微妙的方法进行深思熟虑的权衡的集体能力。

以下是洛克哈特对技术债务的总结:

“技术债务会影响整个开发过程。时期。它可以用来在企业中做出深思熟虑的选择,如果被忽视,它也可以成为一种破坏性力量。”

“雇佣经验丰富的工程师,他们对技术债务有一定的容忍能力,在权衡取舍时也有自己的直觉。寻找考虑正反两面的开发者,而不是绝对的开发者。”

“如果代码对业务至关重要或将影响客户,请立即解决技术债务。但如果债务没有造成任何迫在眉睫的问题,那就监督它,让它过去吧。”

“解决技术债务并不能神奇地使所有代码更容易编写。它是一把双刃剑,既可以是快速部署的杠杆,也可以是糟糕代码的温床。”

“引导你内心的木匠。垫片和夹具可以帮助将技术债务从对技术团队的威胁转变为帮助构建和巩固代码库的工具。”