我们都编写可重用的类和代码。
我们考虑了可配置性,以允许我们一次又一次地重用这个奇妙的新类。
我们告诉我们的老板,现在花费这些额外的时间将为我们以后节省时间和金钱。
但实际上,对于我们这些不编写第三方库并将时间花在整个应用程序上的人来说,有多少次你花费额外时间编写的一个类实际上会在另一个项目中被重用?
您的图书馆中有多少定制课程将用于多个项目?
我们都编写可重用的类和代码。
我们考虑了可配置性,以允许我们一次又一次地重用这个奇妙的新类。
我们告诉我们的老板,现在花费这些额外的时间将为我们以后节省时间和金钱。
但实际上,对于我们这些不编写第三方库并将时间花在整个应用程序上的人来说,有多少次你花费额外时间编写的一个类实际上会在另一个项目中被重用?
您的图书馆中有多少定制课程将用于多个项目?
我的共同经验法则是:
好问题!
我认为“为重复使用而设计”是错误的方法。我发现我编写的代码可以正常工作、干净且漂亮,是可重用的。实际的重用
设计只发生在代码第一次真正被重用时!
事先花时间尝试使某些东西可重用往往是浪费时间,因为您永远不知道需要重用什么。
话虽如此,在我的工作中,我们有一个库集合(大,500MB 或更多),几乎可以在每个项目中重复使用——主要是特定领域的东西。
莱皮写道:
我的共同经验法则是:
- 如果你重复一次,复制它。
- 如果你重复两次,重构它
我还要补充一点,确保在代码的两个部分都添加注释以指示重复,以防出现错误。您不想修复它的一部分而不是另一部分(BDTTGTT)。
抢
我不是 XP 方法(或任何方法)方面的专家,但我认为YAGNI原则可以在这里应用。
仅在必须重用时修改代码以供重用。
可配置性和可重用性之间存在差异——前者在许多不同的情况下非常有用,当环境发生变化或其他任何事情时——以我理解的方式使事物可配置,主要是分离代码和数据的情况——这真的是很好的做法。
仅当您正在创建计划用作多个项目的库时,为可重用性设计才真正有用。随着岁月的流逝,我越来越意识到 YAGNI 原则,这些天我的目标只是为手头的任务编写干净而健壮的代码。我的经验是,如果要重用某些东西,您不太可能准确预测它需要如何重用,因此最好只添加您现在需要的代码。这样,如果您将来需要重用它,您可以添加新的东西来完全满足您的需要,而不必破坏您过去编写的任何现有功能,试图预测您现在可能需要它的方式。
您可能会发现,在这样做几次之后,您就有了一个稳定且健壮的库,并且不需要您更改它,因为它实际上可以完成您需要的所有事情 - 对我来说,允许这种情况发生要容易得多这种进化方式比浪费太多时间猜测未来。
我认为最好的方法是尝试设计具有良好接口和类之间职责分离的代码,而不必过多担心重用。但至少如果你以这种方式设计,你就会留下重用的可能性。一个好的经验法则是问自己“如果我在 3 个月后回到这段代码,我会理解它吗?如果必须的话,我可以扩展它吗?”
IMO 行业中最糟糕的做法之一是当一个团队被允许开始编写他们自己的“可重用”框架时......
我喜欢你不断扩展语言的 LISP 模型。最终,您最终会为您的问题域提供一种特定于域的语言。并不是说我真的写了任何 lisp,而是在我最常使用的语言中——Lua 和 C——我通常将一些东西拉到一个模块中并重用它,而不是克隆和修改。
对于 C 程序员,这种方法的典型例子是 Dave Hanson 的书C 接口和实现。Dave 将他在编写三四个编译器时的每一个可重复使用的想法都写进了一本书中——而且该软件是免费的。很棒的东西。现在,如果我编写 C 代码并且想再次使用它,我会创建一个 Hanson 风格的界面。这个学期我做了一些事情:二维数组、带阻塞的二维数组、二维位图、pbmplus 文件的读取器和写入器,等等。有了这个基础设施,很容易编写一个我多年来一直想要的程序,该程序是从书页影印件的扫描中去除黑边。
所以我同意任何人所说的,当你想重复使用它时,把它拔出来——但不是之前。
恕我直言,某些代码可能会经常被重用,并且为频繁重用做好准备是有意义的。除了解决眼前的问题之外,其他代码不需要,而且可能不需要开发。
当然,请注意区分是 NP 难的。:)
如果您确定不再需要它,请不要打扰。即使您认为它可能会派上用场,也不会。当你真的再次需要它时重构它......
但是,不使其可重用并不是不使其透明的借口。每当我尽可能透明地编写代码时,它总是 99% 可重用......
一旦你超越了技术实用程序的水平,我在现实世界中看到的实际重用很少。
如果你仔细想想,原因就很清楚了。假设 widget_bodger 应用程序包含了您需要的 90% 的功能,而不是仅将缺少的功能添加到应用程序中。
或者说企业很欣赏 widget_bodger 中一个非常酷的“哔”功能,并希望将其整合到 gernerate_executive_expenses 应用程序中。啊,您可能会认为重用,但随后您深入研究代码,发现 GEE 应用程序是公司中最古老的应用程序之一,用 C 编写,必须在高可用硬件上运行,唯一可重用的是基本算法.
关于是什么使代码可重用存在非常不同的意见。我想说你的时间花在使代码清晰和精心设计上(即职责分离)。
这样做的一个附带好处是更好的可重用性。主要好处是使代码更易于理解、更改和调试。
把它包起来。不要仅仅为了使其可重用而做复杂的配置方案、扩展点和事件。尝试找到正确的移动部件,以便可以根据新需求编写代码。
“可重用”代码通常是抽象和模块化的代码,对我来说,主要的好处不是可重用性,而是增加了可测试性。因为当您隔离和模块化代码时,它通常变得更可测试。重用是一种方便但经常未被使用的副作用。
另一方面,Juval Lowry 提倡基于接口的编程,因为他认为接口是可重用性的唯一组成部分。其他任何东西都具有隐含的功能(难以重用),而接口仅定义可隐式重用的合约。
我同意你的观点,因为以一种使类在当前应用程序之外易于使用的方式进行编码是没有意义的。大多数情况下,如果我们不这样做,在商业环境中就没有必要这样做。如果另一个应用程序在以后需要此功能,则可以将代码提取和通用化作为第二个项目的一部分,并且管理层可能会同意这一观点。
然而,让您的代码在当前应用程序的约束下可重用是一种很好的做法。重构您的代码,以避免在您当前的工作范围内重复。这样,您以后可以更轻松地使用它。不要像改变那样重用代码,改变要普遍得多。
我的 2c 是代码重用的道德需要成为公司的事情,而不仅仅是项目的事情。这意味着当您开始一个新项目时,主要关心的是“我可以从哪些其他项目中窃取代码以尽可能快地完成这项工作?”。
这将与“什么是最好的 - 或最流行的 - 工作语言/工具?”的问题相冲突?
采用这种方法的公司最终拥有一批工程师,可以轻松地从一个项目切换到另一个项目,因为语言、框架和内部代码库都是一致的。
不利的一面是,切换到“新”语言或框架在政治上要困难得多,即使它需要在某个时候发生。
SOA 失败或尚未解除的原因之一是很难重用服务:要么它太具体,无法在其他地方使用,要么太通用(通常非常复杂),不能满足不同客户的需求。
这不是“代码重用”,而是“服务重用”,但有一些共同的概念。
重用的另一个好处是您可以轻松地跟踪在 oode 库中发生的事情。如果你有一百万行代码,可能需要几个小时才能找到应用程序以某种方式运行的所有地方。使用现代 IDE,您只需单击“查找引用”,您将在几秒钟内找到使用您的组件/方法的所有位置。当您想要添加新功能、修复错误或只是想了解系统如何工作时,这可能很有用。
我们有一些,但我们有更多的是具有您想要的功能但以自己的方式完成的项目,因此通常您最终会从旧项目中蚕食功能并在新项目中重新实现它们。我认为这仍然很重要 - 您仍然可以从之前编写代码中受益,并且您仍然可以节省时间。
此外,我发现只有第二次尝试使用该功能时,可重用性就变得很明显了,如果您尝试推测性地概括某些东西,您几乎总是会出错,并且下次必须更改它。
就像其他海报所说的那样,如果您要复制代码然后重新使用,一旦您开始调试复制的代码,您会很高兴这样做。