如何使代码可重用? [关闭]
Posted
技术标签:
【中文标题】如何使代码可重用? [关闭]【英文标题】:How do you make code reusable? [closed] 【发布时间】:2010-09-21 01:28:44 【问题描述】:任何代码都可以以某种方式重用,至少在您修改代码时是这样。随机代码本身不是很可重用。当我读一些书时,他们通常说你应该通过考虑代码使用的其他情况来明确地使代码可重用。但是某些代码也不应该是一个万能的全能类。
我想要以后不必更改的可重用代码。如何使代码可重用?代码可重用的要求是什么?哪些东西是可重用代码绝对应该具备的,哪些东西是可选的?
【问题讨论】:
一句警告:“我以后不必更改的可重用代码”不一定是您希望争取的。更改代码本质上并不是消极的。接受重构有时会很有成效。那么,您究竟为什么要让您的代码可重用呢? 当然,如果你愿意的话,将来所有的代码都会变得更好。但是当我制作可重用的代码时,我希望我以后可以直接使用它而无需担心。 我们进入 YAGNI 兔子洞……你真的需要淡化最初的意图以使其超通用,还是坚持手头的任务更好?框架是可重用的,应用程序则不然。这个问题已经有 7 年历史了,所以我认为 OP 现在已经解决了,这是供 Google 同事思考的。只是一个观察。 假设其他人会将您的课程用于各种目的 【参考方案1】:请参阅10 tips on writing reusable code 获取帮助。
-
保持代码干燥。 Dry 的意思是“不要重复自己”。
让一个类/方法只做一件事。
为您的类编写单元测试并简化测试类。
从任何框架代码中删除业务逻辑或主代码
尝试更抽象地思考并使用接口和抽象类。
扩展代码。编写可以在未来轻松扩展的代码。
不要编写不需要的代码。
尽量减少耦合。
更加模块化
编写代码,就像您的代码是外部 API 一样
【讨论】:
这集中在战术上。但是没有好的策略的战术只是没有进步的运动。首先,您需要制定一个可靠的重复使用计划,然后将该计划出售给高级管理层。 #2 很棒。 “做一件事,把它做好”。如果函数/方法真的是自包含的,那么您可以根据需要将它们复制到其他项目中。 #6 更难理解,我认为可能是可以扩展以填满整本书的内容(并且可能已经)...... 对于“最后但并非最不重要”系列。就个人经验而言,我习惯于遵循第十条规则尽可能多地发展。在 MVC 应用程序中,我的控制器只返回一个 JSON。正确的视图将调用该服务并构建网页。通过这种方式,我可以将我的应用程序导出为移动应用程序或独立客户端等。 所有提示都很棒。我认为#10尤其是黄金法则。 我认为这也可能有所帮助:noobieprogrammer.blogspot.com/2020/06/…【参考方案2】:如果您采用测试驱动开发方法,那么您的代码只能根据即将到来的场景作为重构来重用。
就我个人而言,我发现不断重构会产生更简洁的代码,而不是尝试事后猜测我需要为特定类编写代码的场景。
【讨论】:
您说“不断地”,但我觉得这有点含糊,因为这意味着无限地在同一个代码库上工作。你能给我一个更具体的指标吗?您编写一个函数/方法,为它编写一个单元测试,这会导致重构,然后平均有多少次迭代?你怎么知道你什么时候完成了,或者至少可以继续前进?【参考方案3】:最重要的是,可维护性使代码可重用。
可重用性本身很少是一个有价值的目标。相反,它是编写结构良好、易于维护和有用的代码的副产品。
如果您着手编写可重用代码,您经常会发现自己在尝试考虑未来项目中可能需要的行为要求。无论您在这方面做得多么出色,您都会发现这些面向未来的要求是错误的。
另一方面,如果你从当前项目的裸需求开始,你会发现你的代码可以干净、紧凑、优雅。当您在处理另一个需要类似功能的项目时,您自然会调整您的原始代码。
我建议查看您选择的编程语言/范式的最佳实践(例如,Java/C# 类型的模式和 SOLID)、精益/敏捷编程文献,以及(当然)“代码完整”一书。了解这些方法的优缺点将无休止地改进您的编码实践。然后,您的所有代码都将变得可重用 - 但“偶然”,而不是设计。
另外,请看这里:Writing Maintainable Code
【讨论】:
【参考方案4】:在编写相对较大的项目时,您会编写各种模块(部分)。在实践中可重用代码意味着您将创建需要相同功能的其他项目可以使用的库。
因此,您必须为此确定可重用的模块
确定每个模块的核心竞争力。例如,如果您的项目必须压缩文件,您将拥有一个处理文件压缩的模块。做不让它做的不仅仅是一件事。只有一件事。
编写一个库(或类)来处理文件压缩,除了要压缩的文件、输出和压缩格式之外,不需要任何其他东西。这将使模块与项目的其余部分分离,使其能够在不同的设置中(重新)使用。
您不必在第一次就将其完美,当您真正重用该库时,您可能会发现设计中的缺陷(例如,您没有将其模块化到能够轻松添加新的压缩格式),您可以第二次修复它们并提高模块的可重用性。您重复使用它(并修复缺陷)的次数越多,它就越容易重复使用。
要考虑的最重要的事情是解耦,如果编写紧耦合的代码,可重用性是第一个牺牲品。
将所有需要的状态或上下文留在库之外。添加方法以指定库的状态。
【讨论】:
我喜欢图书馆的想法。然后很清楚,当可重用代码在库中时。【参考方案5】:对于“重用”的大多数定义,代码的重用是一个神话,至少在我的经验中是这样。你能说我有一些伤疤吗? :-)
通过重用,我并不是指获取现有的源文件并在新组件或服务退出之前将它们提交提交。我的意思是采用特定的组件或服务并在不改变的情况下重复使用它。
我认为第一步是让自己进入一种心态,即创建一个可重用的组件至少需要 3 次迭代。为什么是3?因为当你第一次尝试重用一个组件时,你总是会发现一些它无法处理的东西。所以你必须改变它。这种情况会发生几次,直到最终您拥有一个至少看起来可重用的组件。
另一种方法是进行昂贵的前瞻性设计。但是成本都是前期的,收益(可能)会在一段时间后出现。如果你的老板坚持当前的项目进度总是占主导地位,那么这种方法就行不通了。
【讨论】:
【参考方案6】:面向对象允许您将代码重构为超类。这可能是最简单、最便宜和最有效的重用类型。普通的类继承不需要过多考虑“其他情况”;您不必构建“全能”代码。
除了简单的继承之外,重用是您发现的比您发明的更多的东西。当您想重用自己的一个包来解决稍微不同的问题时,您会发现重用情况。当您想重用一个不完全适合新情况的包时,您有两种选择。
复制并修复它。您现在必须使用几乎相似的软件包——这是一个代价高昂的错误。
使原始包在两种情况下可重复使用。
这样做是为了重复使用。而已。过多考虑“潜在”重用和未定义的“其他情况”可能会浪费时间。
【讨论】:
【参考方案7】:其他人已经提到了这些策略,但在这里他们是正式的。这三个会让你走得很远:
遵守Single Responsibility Principle - 它可以确保您的课程只“做一件事”,这意味着它更有可能被包含相同内容的另一个应用程序重用。 遵守Liskov Substitution Principle - 它可以确保您的代码“毫无意外地完成它应该做的事情”,这意味着它更有可能被另一个需要完成相同事情的应用程序重用。 遵守Open/Closed Principle - 它确保您的代码可以在不修改其源代码的情况下表现出不同的行为,这意味着它更有可能在不直接修改的情况下被重用。【讨论】:
【参考方案8】:要添加到上述项目,我会说:
将那些需要重用的函数设为通用 使用配置文件并使代码使用files/db中定义的属性 清楚地将您的代码分解为提供独立功能且可用于不同场景的函数/类,并使用配置文件定义这些场景【讨论】:
【参考方案9】:我会添加“类组合优于类继承”的概念(源自此处的其他答案)。 这样,“组合”对象不关心它所依赖的对象的内部结构——只关心它的行为,这会导致更好的封装和更容易的可维护性(测试,需要关心的细节更少)。 在 C# 和 Java 等语言中,这通常很重要,因为没有多重继承,因此它有助于避免您可能遇到的继承图地狱。
【讨论】:
【参考方案10】:如前所述,模块化代码比非模块化代码更具可重用性。
帮助实现模块化代码的一种方法是使用封装,请参阅此处的封装理论: http://www.edmundkirwan.com/
编。
【讨论】:
【参考方案11】:避免重新发明***。而已。这本身就有很多上面提到的好处。如果您确实需要更改某些内容,那么您只需创建另一段代码、另一个类、另一个常量、库等...它可以帮助您和其他开发人员在同一个应用程序中工作。
【讨论】:
【参考方案12】:评论,详细说明,当您下次回到代码时,所有看起来可能会令人困惑的东西。过于冗长的 cmets 可能会有点烦人,但它们比稀疏 cmets 好得多,并且可以节省数小时试图弄清楚你上次在做什么的 WTF。
【讨论】:
以上是关于如何使代码可重用? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章