12

几年前,媒体上充斥着各种各样的文章,说明代码重用的想法是如何提高生产力和代码质量的一种简单方法。

从我定期查看的博客和网站来看,“代码重用”的想法似乎已经过时了。也许“代码重用”的倡导者都加入了 SOA 的行列?:-)

有趣的是,当您在 Google 中搜索“代码重用”时,第二个结果的标题是:

“内部代码重用被认为是危险的”!

代码重用的想法对我来说只是常识,毕竟看看 apache commons 项目的成功!

我想知道的是:

  • 您或您的公司是否尝试重用代码?
  • 如果是这样,如何以及在什么级别,即低级 api、组件或共享业务逻辑?您或您的公司如何重用代码?
  • 它有效吗?

讨论?


我完全意识到有许多可用的开源库,并且任何使用过 .NET 或 Java 的人都以某种形式重用了代码。这是常识!

我更多地指的是组织内的代码重用,而不是通过共享库等跨社区重用。

我最初问的是;

  • 您或您的公司是否尝试重用代码?
  • 如果是这样,如何以及在什么级别,即低级 api、组件或共享业务逻辑?您或您的公司如何重用代码?

从我坐的地方,我看到很少有公司试图在内部重用代码的例子?

如果您有一段可能在中型组织中共享的代码,您将如何通知公司的其他成员该 lib/api/etc 存在并且可能有用?

4

16 回答 16

10

您所指的文章的标题具有误导性,实际上是一本非常好的读物。代码重用是非常有益的,但任何事情都有缺点。基本上,如果我没记错的话,这篇文章的主旨是你将代码密封在一个黑盒子里,而不是重新访问它,所以当原始开发人员离开时,你就会失去知识。虽然我明白这一点,但我不一定同意它——至少不赞成“天塌下来”的看法。

实际上,我们将代码重用分组为不仅仅是可重用的类,我们着眼于整个企业。更像是框架增强或解决横切关注点的东西被放入我们所有应用程序都使用的开发框架中(想想验证前和验证后、日志记录等)。我们还有适用于多个应用程序的业务逻辑,因此这些事情被转移到可在任何地方访问的 BAL 核心。

我认为重要的是,如果它们不会真正被重用,就不要提倡重用。它们应该有很好的文档记录,以便新开发人员也可以拥有资源来帮助他们跟上进度。很有可能,如果不共享知识,代码最终会在其他地方重新发明,如果您在文档和知识共享方面不严格,则会导致重复。

于 2008-12-10T14:50:58.203 回答
5

我们重用代码——事实上,我们的开发人员专门编写可以在其他项目中重用的代码。这得到了很好的回报——我们能够快速启动新项目,并且我们迭代地强化我们的核心库。

但是不能只写代码并期望它被重用;代码重用需要团队成员和其他用户之间的沟通,以便人们知道哪些代码可用,以及如何使用它。

要使代码重用有效地工作,需要以下几点:

  • 代码或库本身
  • 跨多个项目或工作对代码的需求
  • 代码特性/功能的通信
  • 关于如何使用代码的说明
  • 承诺随着时间的推移维护和改进代码
于 2008-12-10T15:27:30.673 回答
3

代码重用是必不可少的。我发现它也迫使我尽可能地概括,也使代码更适应不同的情况。理想情况下,您编写的几乎每个较低级别的库都应该能够适应不同应用程序的一组新要求。

于 2008-12-10T15:09:51.457 回答
2

我认为代码重用在很大程度上是通过开源项目完成的。任何可以重用或扩展的东西都是通过库来完成的。Java 有数量惊人的开源库可用于做大量的事情。将其与 C++ 进行比较,以及使用 MFC 或 Win32 API 从头开始​​实现所有内容的时间有多早。

于 2008-12-10T14:45:32.287 回答
1

我们重用代码。

在小范围内,我们尽量避免代码重复。我们有一个完整的库,里面有很多常用的代码。

通常代码是为一个应用程序开发的。如果它足够通用,它就会被提升到库中。这效果很好。

于 2008-12-10T14:41:46.273 回答
1

代码重用的想法不再是一个新颖的想法......因此显然缺乏兴趣。但这仍然是一个好主意。整个 .NET 框架和 Java API 都是代码重用的好例子。

我们已经习惯于为我们的项目开发 OO 代码库并在其他项目中重用它们。它是一个想法的自然生命周期的一部分。争论了一会,大家都接受了,没有再讨论的理由了。

于 2008-12-10T14:46:04.080 回答
1

当然我们重用代码。

有几乎无限数量的可用于所有语言的包、库和共享对象,整个开发人员社区都在支持和更新它们。

于 2008-12-10T14:46:16.140 回答
1

我觉得没有“媒体关注”是因为大家都在做,不值得再写了。我没有听到很多人像以前那样提高对面向对象编程和单元测试的认识。每个人都已经知道这些概念(无论他们是否使用它们)。

于 2008-12-10T14:57:13.090 回答
1

媒体对一个问题的关注程度与其重要性无关,无论我们是在谈论软件开发还是政治!避免因重新发明(或重新维护!)轮子而浪费开发工作很重要,但现在这已广为人知,编辑可能不会对有关该主题的另一篇文章感到兴奋。

与其将当前文章和博客文章的数量作为衡量重要性(或紧迫性)的标准,不如关注已成为经典或进入行话的概念和流行语(另一种重用形式!)例如,Google for uses DRY 的首字母缩写词,用于很好地讨论可以在软件和开发过程中消除的多种形式的冗余。

对重用成本与在何处实现收益进行成熟判断也有一定的作用。一些作者主张等到真正出现第二次或第三次使用时再担心重用,而不是在第一次编写代码时花精力概括代码。

于 2008-12-11T13:10:53.147 回答
1

我个人的看法,基于我公司的实践:

  • 您或您的公司是否尝试重用代码?

显然,如果我们有另一段代码已经满足我们的需求,我们将重用它。不过,我们不会特意在圆孔中使用方钉。

  • 如果是这样,如何以及在什么级别,即低级 api、组件或共享业务逻辑?您或您的公司如何重用代码?

在每个级别。它被写入我们的编码标准,开发人员应该始终假设他们的代码将被重用——即使实际上这极不可能。见下文

如果您的 OO 模型很好,您的 API 可能反映了您的业务领域,因此可重用类可能等同于可重用业务逻辑而无需额外的努力。

对于实际重用,一个关键点是知道哪些代码已经可用。我们通过将所有内容记录在一个中心位置来解决这个问题。我们只需要一点纪律来确保文档是最新的并且可以以有意义的方式进行搜索。

  • 它有效吗?

是的,但不是因为潜在的或实际的重用!实际上,除了几个核心库和 UI 组件之外,并没有大量的重用。

在我个人看来,真正的价值在于使代码可重用。在这样做的过程中,除了一个希望更清洁的 API 之外,代码将 (a) 有足够的文档记录以供其他开发人员使用它而无需搜索源代码,并且 (b) 它也将是可替换的。这些点对持续的软件维护有很大的好处。

于 2009-07-30T11:36:09.147 回答
1

您或您的公司是否尝试重用代码?如果是这样,如何以及在什么级别,即低级 api、组件或共享业务逻辑?您或您的公司如何重用代码?

我曾经在一个代码库中工作,使用 uber 代码重用,但由于重用代码不稳定,因此很难维护。它很容易以级联到所有使用它的方式进行设计更改和弃用。在此之前,我在一个没有代码重用的代码库中工作,其中老年人实际上鼓励复制和粘贴作为重用甚至应用程序特定代码的一种方式,所以我看到了两个极端,我不得不说一个不一定很多在极端情况下比另一个更好。

我曾经是一个超级自下而上的程序员。你让我构建一些特定的东西,我最终构建了通用工具。然后使用这些工具,我构建了更复杂的通用工具,然后开始构建 DIP 抽象来表达低级工具的设计要求,然后我构建更复杂的工具并重复,在某个时候我开始编写真正的代码你要我做什么。尽管这听起来适得其反,但我的速度非常快,并且可以以令人惊讶的方式运送复杂的产品。

问题是几个月、几年的维护!在我构建了这些通用库的一层又一层并重用它们之后,每个人都希望服务于比您要求我做的更大的目的。每一层都想解决世界的饥饿需求。所以每个人都非常雄心勃勃:一个想要令人惊叹并解决世界饥饿需求的数学图书馆。然后建立在数学库之上的东西,比如想要令人惊叹并解决世界饥饿需求的几何库。当您尝试发布产品时,您知道出了点问题,但是当您应该处理动画时,您的大脑正在考虑您的超级通用几何库在渲染和建模方面的效果如何,因为您正在处理的动画代码on 需要一些新的几何函数。

平衡每个人的需求

我发现在设计这些超级通用的库时,我必须着迷于每个团队成员的需求,我必须学习光线追踪是如何工作的,流体动力学是如何工作的,网格引擎是如何工作的,反向运动学是如何工作的,如何角色动画工作,等等等等等等。我必须学习如何完成团队中几乎每个人的工作,因为我在设计这些超级通用库时平衡了他们的所有特定需求,我在走钢丝平衡行为时留下了所有代码重用的设计妥协(试图让正在使用其中一个库的 Bob 进行光线跟踪但又不会伤害到 John 正在研究物理的同时也在使用它但不会使库的设计复杂化的情况太多了,无法让他们俩都开心)。

到了这样一个地步,我试图用策略类对边界框进行参数化,以便它们可以存储为一个人想要的中心和一半大小,或者其他人想要的最小/最大范围,并且实现变得非常复杂快速尝试疯狂地跟上每个人的需求。

委员会设计

而且由于每一层都试图满足如此广泛的需求(比我们实际需要的要广泛得多),他们找到了许多需要更改设计的理由,有时是委员会要求的设计(通常有点粗俗)。然后这些设计更改会向上级联并影响所有使用它的更高级别的代码,并且这些代码的维护开始成为真正的 PITA。

我认为您可以在志同道合的团队中共享更多代码。我们的想法完全不同。这些不是真名,但我这里有比尔,他是一个高级 GUI 程序员和脚本编写者,他创建了很好的用户端设计,但有很多 hack 的有问题的代码,但对于那种类型的代码来说往往没问题。我在这里找到了 Bob,他是一位自打孔卡时代以来一直在编程的老手,他喜欢编写带有 goto 的 10,000 行函数,但仍然不明白面向对象编程的重点。我在这里找到了乔,他就像一个数学向导,但编写的代码没有其他人可以理解,并且总是提出数学上一致的建议,但从计算的角度来看不一定如此有效。

试图在想出一个体面的设计的同时满足这里每个人的需求,回想起来可能是不可能的。在每个人都试图分享彼此的代码时,我认为我们变得适得其反。每个人都在某个领域胜任,但试图提出每个人都满意的设计和标准只会导致各种不稳定并减慢每个人的速度。

权衡取舍

所以这些天我发现平衡是避免代码重用最底层的东西。我可能会使用中层自上而下的方法(与您要求我做的事情相差不远),并在那里建立一些独立的图书馆,我仍然可以在很短的时间内完成,但是图书馆不打算生产试图解决世界饥饿需求的迷你库。通常,此类库的用途比较低级别的库要窄一些(例如:物理库,而不是广义几何交叉库)。

YMMV,但是如果这些年来我以最艰难的方式学到了什么,那就是可能存在一种平衡行为,并且我们可能希望在某个细粒度级别故意避免在团队设置中重用代码,放弃一些支持解耦的最低级别代码的通用性,拥有可延展的代码,我们可以更好地塑造以服务于更具体而不是笼统的需求,等等——甚至可能只是让每个人都有更多的自由以自己的方式做事。但是当然所有这一切都是为了仍然产生一个非常可重用的通用库,但不同的是,库可能不会分解成最小的通用库,因为我发现跨越某个阈值并试图制造太多蝇头,

如果您有一段可能在中型组织中共享的代码,您将如何通知公司的其他成员该 lib/api/etc 存在并且可能有用?

这些天我实际上更不情愿,如果同事做一些多余的工作,我会觉得更可原谅,因为我想确保代码做一些相当有用和不平凡的事情,并且在我尝试分享之前也经过很好的测试和设计和人在一起,积累了一堆对它的依赖。如果我与团队的其他成员分享,那么从那时起,设计应该有非常非常少的理由要求进行任何更改。

否则,它可能会导致比实际节省更多的悲伤。

我曾经非常不能容忍冗余(在代码或工作中),因为它似乎转化为一个在内存使用方面非常有问题和爆炸性的产品。但是我把冗余作为关键问题过分强调了,而真正的问题是质量差、仓促编写的代码以及缺乏可靠的测试。即使有些人在这里和那里复制一些数学函数,经过良好测试、可靠、高效的代码也不会在很大程度上受到这个问题的影响。

要注意并记住我当时没有注意的常识之一是,当我们使用非常可靠的第三方库时,我们如何不介意一些冗余。你们可能会使用一两个第三方库,这些库与您的团队正在做的事情有一些多余的工作。但是我们不介意在这些情况下,因为第三方库很棒并且经过了很好的测试。我建议将相同的思维方式应用于您自己的内部代码。目标应该是创建一些很棒且经过良好测试的东西,而不是像我很久以前错误地做的那样在这里和那里大惊小怪。

因此,这些天来,我已经将我的不容忍转变为缺乏测试。与其对多余的工作感到不安,我发现对其他人缺乏单元和集成测试感到不安更有效率!:-D

于 2018-02-05T06:00:25.907 回答
0

虽然我认为代码重用很有价值,但我可以看到这种情绪的根源。我参与过很多项目,在这些项目中,我特别注意创建可重用的代码,而这些代码从未被重用过。当然重用比复制代码更可取,但是我已经看到了许多非常广泛的对象模型,其目标是在多个项目中跨企业使用对象(就像 SOA 中的相同服务可以在不同的项目中使用的方式一样)应用程序),但从未见过实际使用过多次的对象。也许我只是没有加入充分利用重用原则的组织。

于 2008-12-10T15:21:36.037 回答
0

也许更好的问题是这些天我们什么时候不重用代码?我们要么处于使用其他人观察到的“最佳实践”或预先发现的“设计模式”构建的状态,要么实际上只是在遗留代码、库或复制上构建。

似乎代码 A 被重用于代码 B 的程度通常取决于代码 A 中用于代码 B 的想法被抽象为设计模式/习语/书籍/短暂的想法/实际代码/库的程度。困难的部分是将所有这些好的想法应用到您的实际代码中。

非技术人员对重用的事情过于热心。他们不明白为什么所有东西都不能复制粘贴。他们不明白为什么 greemelfarm 需要一个特殊的适配器来将与旧系统相同的信息传递给新系统,不幸的是,由于无数其他原因,我们也无法更改。

我认为技术人员从第一天开始就一直在重复使用,就像音乐家从第一天开始重复使用一样。这是一个持续的有机进化和综合,将继续进行。

于 2008-12-10T15:22:24.320 回答
0

我从事的两个软件项目都是长期开发的。一个大约有 10 年的历史,另一个已经存在了 30 多年,一路上用几个版本的 Fortran 重写。两者都广泛重用代码,但都很少依赖外部工具或代码库。DRY 是新项目的一个重要口头禅,它使用 C++,在实践中更容易做到这一点。

于 2008-12-10T15:26:13.593 回答
0

代码重用是一个极其重要的问题——如果代码没有被重用,项目需要更长的时间,并且新团队成员更难进入。
但是,编写可重用代码需要更长的时间。

就个人而言,我尝试以可重用的方式编写所有代码,这需要更长的时间,但这导致我的大部分代码已成为我组织中的官方基础架构,并且基于这些基础架构的新项目所需的时间明显减少。

重用代码的危险在于,如果重用代码不是作为基础设施编写的——以一种通用和封装的方式,尽可能少的假设和尽可能多的文档和单元测试,那么代码最终可能会做意想不到的事情。
此外,如果发现并修复了错误或添加了功能,这些更改很少会返回到源代码中,从而导致重用代码的不同版本,没人知道或理解。

解决方案是:
1. 设计和编写代码时不仅要考虑一个项目,还要考虑未来的需求,并尝试使设计足够灵活,以最少的代码更改覆盖它们。
2. 将代码包含在要按原样使用且未在使用项目中修改的库中。
3. 允许用户查看和修改库的代码及其解决方案(不在使用项目的解决方案内)。
4. 在现有基础设施的基础上设计未来的项目,必要时对基础设施进行更改。
5. 负责对所有项目的基础设施进行维护,从而保持基础设施的资金来源。

于 2009-02-07T14:11:34.570 回答
-1

Maven 解决了代码重用问题。我是认真的。

于 2008-12-25T08:36:47.250 回答