可重用性是一个谬论 - UWE FRIEDRICHSEN


多年来,可重用性/可复用性是软件架构设计中的一个圣杯。关于可重用软件模块的讨论在1970年代初得到了发展。例如,1974年史蒂文斯,迈尔斯和君士坦丁(Stevens,Myers和Constantine)撰写的开创性的计算机科学论文“结构化设计”Structured design)已经讨论了将可重用性作为结构化设计的目标之一。
讨论一直持续到今天。诚然,这个想法很有趣:我只创建了一个软件模块,并且由于基本上没有软件的复制成本,所以我可以在任意多个地方免费使用它。投资一次,永远收获。多么有效的杠杆!节省成本!
因此,毫不奇怪的是,几代IT经理都要求可重用性是必不可少的设计目标,而作为他们的大祭司,作为回报的架构师则努力提供可重用性。随着时间的流逝,对可重用性的渴望已变得独立。在给定的环境下,没有人再问过可重用性是否有意义。
从我在IT生涯中所看到的一切来看,可重用性从来没有节省投资,我敢肯定,将来它也将永远无法有效。
原因有多个方面:
首先,可重用性是一种深厚的工业信念。在物理世界中,可重用性在大多数情况下可以与标准化互换。标准化零件支持以较低的价格构建产品,并且可以轻松地在多个产品中重复使用。另一方面,在设计时考虑到可重用性的任何零件都可以成为标准化零件的候选人。
物理世界中可重用性/标准化的关键方面在于,随着时间的推移,它有助于节省成本。您只需花费一次设计零件的时间即可。生产过程只需要设计和设置一次。所需的工具只需创建和安装一次。之后,您可以制作所需数量的零件副本,而无需重复设计和设置投资。
这样,可重用性有助于满足工业市场的关键成功标准:以经济高效的方式扩大规模。成本节省的很大一部分来自零件的生产,您可以生产很多零件,而不必一遍又一遍地设计和设置生产过程以及工具。
如果您以可以在不同上下文中(重复)使用的方式另外创建零件,则可以产生更大的数量,这有助于进一步分散设计和设置的固定成本,即零件变得更便宜
因此,在可重用零件创建房屋,桥梁,家具,电子设备等的物理世界中,始终如一地追求可重用性是很有意义的。但是,将这种通过可重用性来节省成本的想法转移到软件开发中会遇到许多警告。

实施是设计的一部分而不是生产的一部分
第一个长期的误解是,可以将编写代码与建造房屋或组装汽车相提并论。这个想法是,可以将软件体系结构和设计工作与设计汽车或房屋,并编写代码来执行计划(即组装最终产品)进行比较。
不幸的是,这种看法是完全错误的。软件开发的最终产品是可执行程序。我们通常通过编译源代码4来创建它。换句话说:IT可能拥有60多年以来可以想象到的最高效的生产流程,因为它是如此高效,以至于我们通常完全忘记了它。
今天,这种生产过程通常是CI / CD流程中的一个步骤,但是它并没有改变我们在没有任何人工干预的情况下以极其有效的方式构建产品的事实。
另一方面,编写代码可以完成设计。产品设计仅在编写最后一行源代码之后才能完成。编写代码就像添加汽车设计的详细信息,设计形状,内部设计,动力传输等的详细信息一样,这是生产汽车之前需要完成的所有工作。生产实际产品时,从代码上执行的程序在时间,成本和工作量方面都是可以忽略的。

编写代码即可完成设计。
从完成的设计中构建产品只是发出命令(与编写代码无关)。

因此,所有将编写代码与组装汽车或盖房相比较的隐喻都是错误的。
这也意味着从物理世界得出的假设被打破了,即通过使用可重复使用的零件,我们可以在生产过程中节省大量资金。与任何物理领域相比,IT的生产过程已经令人难以置信地便宜。此外,我们可以以零成本生产零件的许多副本:这称为复制命令。
因此,基于物理世界中可重用性价值的所有考虑因素都不适用于IT,因为软件开发中的可重用性无助于在生产过程中节省成本。

IT固有的缺乏标准化
通过设计过程中的可重用性,这仍然留有提高效率的空间。再次(误用)汽车的隐喻:如今,许多汽车制造商使用平台策略,即,他们在汽车设计中重复使用了许多标准化的基础部件。例如,他们不会为他们设计的每个新模型从头开始设计引擎或底盘,而是从平台上重复使用引擎或底盘,并为特定模型单独设计零件进行补充。
虽然这种再次使用零件的平台方法主要是针对节省生产方面的成本(这与IT无关,正如我们在上一节中所看到的),但它也可能有助于减少设计过程中的时间,成本和工作量。
我们可以将这种思想应用于软件开发:在设计中可以使用的可重用部分越多,即软件开发过程,可以节省的时间,成本和精力就越多。
这是IT另一个特殊之处。
弗雷德·布鲁克(Fred Brook)在其著名的论文“没有灵丹妙药” [url=https://www.ufried.com/blog/reusability_fallacy_1/fn:5]5[/url]中解释了软件开发中必不可少和偶然的复杂性。他列出的基本复杂性的驱动因素之一是“复杂性”:

软件实体的大小可能比任何其他人工构造的都要复杂,因为没有两个部分是相同的(至少在声明级别之上)。如果是这样,我们将两个相似的部分合为一个子例程,即打开或关闭。在这方面,软件系统与计算机,建筑物或汽车有着千丝万缕的区别。[…]同样,软件实体的扩展不仅仅是重复相同的元素,而且尺寸更大。它必然会增加不同元素的数量。

首先,布鲁克斯显然拒绝了这样的想法,即我们可以按照与我们通过多次布置相同类型的砖块来设计墙的方式相同的方式,从一组更高级别的标准化构件中设计软件解决方案。我们使用的每个部分都会与其他所有部分不同。
然而,尽管使用标准化的构建块作为依据,布鲁克斯仍然留有重用的余地:他指出我们解决方案中的每个部分都会有所不同,但在更高层次的环境中,我们可能会多次使用该部分。遵循这个想法,我们重用了较低级别的功能来支持较高级别的功能。

剩下的可重用性
在这篇文章中,我试图解构一部分可重用性谬论:这种谬论是,通过使用标准化的可重用部件,我们可以从更高效的生产过程中节省很多钱。软件开发与设计有关。仅在编写最后一行代码之后,设计才完成。
实际的生产过程(即创建可执行程序)是如此高效且廉价,以至于没有什么可节省的。因此,所有从物理世界中获取概念并将其应用于软件开发的可重用性方法都行不通。