46

任何代码都可以以某种方式重用,至少在您修改代码时是这样。随机代码本身不是很可重用。当我读一些书时,他们通常说你应该通过考虑其他代码使用情况来明确地使代码可重用。但是某些代码也不应该是一个无所不能的全能类。

我想拥有以后不必更改的可重用代码。如何使代码可重用?代码可重用的要求是什么?可重用代码绝对应该具备哪些东西,哪些东西是可选的?

4

12 回答 12

64

请参阅编写可重用代码的 10 个技巧以获取帮助。

  1. 保持代码干燥。Dry的意思是“不要重复自己”。
  2. 让一个类/方法只做一件事。
  3. 为您的课程编写单元测试并简化测试课程。
  4. 从任何框架代码中删除业务逻辑或主要代码
  5. 尝试更抽象地思考并使用接口和抽象类。
  6. 扩展代码。编写将来可以轻松扩展的代码。
  7. 不要编写不需要的代码。
  8. 尽量减少耦合。
  9. 更加模块化
  10. 编写代码,就像您的代码是外部 API
于 2008-11-06T10:47:46.547 回答
15

如果您采用测试驱动开发方法,那么您的代码只能根据即将到来的场景作为重构来重用。

就我个人而言,我发现不断重构会产生更简洁的代码,而不是试图事后猜测我需要为特定类编写代码的场景。

于 2008-11-06T10:51:18.630 回答
12

最重要的是,可维护性使代码可重用。

可重用性本身很少是一个有价值的目标。相反,它是编写结构良好、易于维护和有用的代码的副产品。

如果您着手编写可重用代码,您经常会发现自己试图考虑未来项目中可能需要的行为要求。无论您在这方面做得多么出色,您都会发现这些面向未来的要求是错误的。

另一方面,如果你从当前项目的裸需求开始,你会发现你的代码可以干净、紧凑、优雅。当您在另一个需要类似功能的项目上工作时,您自然会调整您的原始代码。

我建议查看您选择的编程语言/范式的最佳实践(例如,Java / C# 类型的模式和 SOLID)、精益 / 敏捷编程文献,以及(当然)“代码完整”一书。了解这些方法的优缺点将无休止地改进您的编码实践。然后,您的所有代码都将变得可重用 - 但“偶然”,而不是设计。

另外,请参见此处:编写可维护的代码

于 2008-11-06T11:30:50.653 回答
7

在编写相对较大的项目时,您将编写各种模块(部分)。在实践中可重用代码意味着您将创建需要相同功能的其他项目可以使用的库。

因此,您必须确定可以重用的模块,为此

  1. 确定每个模块的核心竞争力。例如,如果您的项目必须压缩文件,您将拥有一个处理文件压缩的​​模块。不要让它做超过件事。只有一件事。

  2. 编写一个库(或类)来处理文件压缩,除了要压缩的文件、输出和压缩格式之外,不需要任何其他东西。这将使模块与项目的其余部分分离,使其能够在不同的设置中(重新)使用。

  3. 您不必在第一次就将其完美,当您实际重用该库时,您可能会发现设计中的缺陷(例如,您没有将其模块化到能够轻松添加新压缩格式的程度)并且您可以第二次修复它们并提高模块的可重用性。您重复使用它(并修复缺陷)的次数越多,它就越容易重复使用。

最要考虑的就是解耦,如果写紧耦合的代码,重用性是第一个牺牲品。

将所有需要的状态或上下文留在库之外。添加方法以指定库的状态。

于 2008-11-06T10:57:23.220 回答
7

对于“重用”的大多数定义,代码的重用是一个神话,至少在我的经验中是这样。你能说我有一些伤疤吗?:-)

通过重用,我并不是指获取现有的源文件并将它们击败提交,直到新的组件或服务失效。我的意思是采用特定的组件或服务并在不改变的情况下重复使用它。

我认为第一步是让自己进入一种心态,即至少需要 3 次迭代才能创建一个可重用的组件。为什么是3?因为当你第一次尝试重用一个组件时,你总是会发现一些它无法处理的东西。所以你必须改变它。这种情况发生了几次,直到最终您拥有一个至少看起来可重用的组件。

另一种方法是进行昂贵的前瞻性设计。但是成本都是前期的,收益(可能)会在一段时间后出现。如果你的老板坚持当前的项目进度总是占主导地位,那么这种方法就行不通了。

于 2008-11-06T12:35:11.663 回答
6

面向对象允许您将代码重构为超类。这可能是最简单、最便宜和最有效的重用类型。普通的类继承不需要过多考虑“其他情况”;您不必构建“全能”代码。

除了简单的继承之外,重用是你发现的比你发明的更多的东西。当您想重用自己的一个包来解决稍微不同的问题时,您会发现重用情况。当你想重用一个不完全适合新情况的包时,你有两个选择。

  1. 复制它并修复它。您现在必须使用几乎相似的软件包——这是一个代价高昂的错误。

  2. 使原始包在两种情况下可重复使用。

这样做是为了重用。而已。过多地考虑“潜在的”重用和未定义的“其他情况”可能会浪费时间。

于 2008-11-06T11:54:30.217 回答
4

其他人已经提到了这些策略,但在这里它们是正式的。这三个会让你走得很远:

  • 坚持单一职责原则——它确保你的类只“做一件事”,这意味着它更有可能被另一个包含同样事情的应用程序重用。
  • 遵守Liskov 替换原则——它可以确保你的代码“毫无意外地完成它应该做的事情”,这意味着它更有可能被另一个需要完成相同事情的应用程序重用。
  • 坚持开放/封闭原则- 它确保您的代码可以在不修改其源代码的情况下表现出不同的行为,这意味着它更有可能在不直接修改的情况下被重用。
于 2008-11-06T13:01:33.310 回答
1

要添加到上述项目,我会说:

  • 使您需要重用的那些功能通用
  • 使用配置文件并使代码使用 files/db 中定义的属性
  • 清楚地将您的代码分解为提供独立功能并且可以在不同场景中使用的函数/类,并使用配置文件定义这些场景
于 2008-11-06T11:08:55.317 回答
1

我将添加“类组合优于类继承”的概念(源自此处的其他答案)。这样,“组合”对象不关心它所依赖的对象的内部结构——只关心它的行为,这会导致更好的封装和更容易的可维护性(测试,需要关心的细节更少)。在 C# 和 Java 等语言中,这通常很重要,因为没有多重继承,因此它有助于避免您可能遇到的继承图地狱。

于 2008-11-06T11:26:36.513 回答
1

如前所述,模块化代码比非模块化代码更可重用。

帮助模块化代码的一种方法是使用封装,请参阅此处的封装理论: http ://www.edmundkirwan.com/

埃德。

于 2008-11-06T11:48:18.607 回答
1

避免重新发明轮子。就是这样。这本身就有很多上面提到的好处。如果您确实需要更改某些内容,那么您只需创建另一段代码、另一个类、另一个常量、库等……它可以帮助您和其他开发人员在同一个应用程序中工作。

于 2009-10-01T23:07:03.670 回答
0

详细评论,当你下次回到代码时,所有看起来可能会令人困惑的东西。过于冗长的评论可能会有点烦人,但它们比稀疏的评论要好得多,并且可以节省数小时试图弄清楚你上次在做什么的 WTF。

于 2012-06-13T07:43:26.807 回答