代码重用和重构

发布于 2024-07-24 04:19:55 字数 1431 浏览 11 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

飘过的浮云 2024-07-31 04:19:55

每行代码都有成本。

研究表明成本与代码行数不是线性的,而是呈指数关系。

复制/粘贴编程是重用软件最昂贵的方式。

“重用是否需要无懈可击的单元测试?”

不。

所有代码都需要充分的单元测试。 所有代码都可以重用。

Every line of code has a cost.

Studies show that the cost is not linear with the number of lines of code, it's exponential.

Copy/paste programming is the most expensive way to reuse software.

"does reuse require watertight unit tests?"

No.

All code requires adequate unit tests. All code is a candidate for reuse.

意中人 2024-07-31 04:19:55

在我看来,在多个地方使用的一段代码有可能针对一个地方而不是另一个地方进行更改,这不符合正确的范围规则。 如果两个不同的事物需要“相同”的方法/类来执行两个不同的功能,那么应该将该方法/类分开。

不要复制/粘贴。 如果您确实需要修改某个地方的代码,那么您可以扩展它,可能通过继承、重载,或者如果必须的话,复制和粘贴。 但不要从复制粘贴相似的片段开始。

It seems to me that a piece of code that is used in multiple places that has the potential to change for one place and not for another place isn't following proper rules of scope. If the "same" method/class is needed by two different things to do two different functions, then that method/class should be split up.

Don't copy/paste. If it does turn out that you need to modify the code for one place, then you can extend it, possibly through inheritance, overloading, or if you must, copying and pasting. But don't start out by copy-pasting similar segments.

行雁书 2024-07-31 04:19:55

使用复制和粘贴几乎总是一个坏主意。 正如您所说,您可以进行测试来检查是否损坏了某些东西。

关键是,当你调用一个方法时,你不应该真正关心它是如何工作的,而是关心它做了什么。 如果你改变了这个方法,改变了它的作用,那么它应该是一个新的方法,或者你应该检查这个方法在哪里被调用。

另一方面,如果更改没有修改该方法的功能(仅修改方法),那么您在其他地方就不应该遇到问题。 如果你这样做了,那你就做错事了……

Using copy and paste is almost always a bad idea. As you said, you can have tests to check in case you break something.

The point is, when you call a method, you shouldn't really care about how it works, but about what it does. If you change the method, changing what it does, then it should be a new method, or you should check wherever this method is called.

On the other side, if the change doesn't modify WHAT the method does (only how), then you shouldn't have a problem elsewhere. If you do, you've done something wrong...

撩人痒 2024-07-31 04:19:55

复制和粘贴的一种非常合适的用法是三角测量。 为一种情况编写代码,查看有一些变化的第二个应用程序,复制并复制它。 粘贴到新的上下文中 - 但你还没有完成。 如果你在那个时候停下来,你就会遇到麻烦。 复制此代码(可能有微小的变化)会公开您的代码所需的一些常见功能。 一旦它在两个地方都经过测试并且在两个地方都工作,您应该将该共性提取到一个地方,从两个原始位置调用它,然后(当然)重新测试。

如果您担心从多个地方调用的代码会带来脆弱性的风险,那么您的函数可能不够细粒度。 过于粗粒度的函数,功能过多的函数,难以重用、难以命名、难以调试。 找到功能的原子部分,命名它们,然后重用它们。

One very appropriate use of copy and paste is Triangulation. Write code for one case, see a second application that has some variation, copy & paste into the new context - but you're not done. It's if you stop at that point that you get into trouble. Having this code duplicated, perhaps with minor variation, exposes some common functionality that your code needs. Once it's in both places, tested, and working in both places, you should extract that commonality into a single place, call it from the two original places, and (of course) re-test.

If you have concerns that code which is called from multiple places is introducing risk of fragility, your functions are probably not fine-grained enough. Excessively coarse-grained functions, functions that do too much, are hard to reuse, hard to name, hard to debug. Find the atomic bits of functionality, name them, and reuse them.

千と千尋 2024-07-31 04:19:55

所以消费者(重用)代码依赖于重用的代码,这是正确的。

您必须管理这种依赖性

对于二进制重用(例如 dll)和代码重用(例如脚本库)也是如此。

  • 消费者应该依赖于重用代码/二进制文件的特定(已知)版本

  • 消费者应保留重用代码/二进制文件的副本,但切勿直接修改它,仅在安全时更新到较新的版本

  • 修改重复使用的代码库时请仔细考虑。 重大更改分支。

  • 如果消费者想要更新重用的代码/二进制文件,那么它首先必须测试它是否安全。 如果测试失败,那么消费者总是可以回退到最后一个已知(并保留)的良好版本。

因此,您可以从重用中受益(例如,您必须在一个地方修复错误),并且您仍然可以控制更改。 但是,每当您更新重用的代码/二进制文件时,没有什么可以阻止您进行测试。

So the consumer (reuser) code is dependent on the reused code, that's right.

You have to manage this dependency.

It is true for binary reuse (eg. a dll) and code reuse (eg. a script library) as well.

  • Consumer should depend on a certain (known) version of the reused code/binary.

  • Consumer should keep a copy of the reused code/binary, but never directly modify it, only update to a newer version when it is safe.

  • Think carefully when you modify resused codebase. Branch for breaking changes.

  • If a Consumer wants to update the reused code/binary then it first has to test to see if it's safe. If tests fail then Consumer can alway fall back to the last known (and kept) good version.

So you can benefit from reuse (eg. you have to fix a bug in one place), and still you're in control of changes. But nothing saves you from testing whenever you update the reused code/binary.

没企图 2024-07-31 04:19:55

是否有最佳实践
问题; 重复使用需要防水吗
单元测试?

是的,有点像是的。 重写已经做过一次的代码从来都不是一个好主意。 如果你从不重用代码而只是重写它,那么你的错误面就会加倍。 与许多最佳实践类型问题一样,代码完成改变了我的工作方式。 是的,尽最大努力进行单元测试,是的,重用代码并获取 代码完整的副本 然后你就准备好了。

Is there a best practice for this
problem; does reuse require watertight
unit tests?

Yes and sort of yes. Rewriting code you have already did right once is never a good idea. If you never reuse code and just rewrite it you are doubling you bug surface. As with many best practice type questions Code Complete changed the way I do my work. Yes unit test to the best of your ability, yes reuse code and get a copy of Code Complete and you will be all set.

慕烟庭风 2024-07-31 04:19:55

复制和粘贴从来都不是好习惯。 有时,在相当糟糕的代码库中作为短期修复似乎更好,但在设计良好的代码库中,您将拥有以下提供轻松重用的功能:

  • 封装
  • 定义良好的接口
  • 对象之间的松耦合(很少依赖)

如果您的代码库展示了这些属性,复制和粘贴看起来永远不会是更好的选择。 正如 S Lott 所说,不必要地增加代码库的大小会带来巨大的成本。

Copy and pasting is never good practice. Sometimes it might seem better as a short-term fix in a pretty poor codebase, but in a well designed codebase you will have the following affording easy re-use:

  • encapsulation
  • well defined interfaces
  • loose-coupling between objects (few dependencies)

If your codebase exhibits these properties, copy and pasting will never look like the better option. And as S Lott says, there is a huge cost to unnecessarily increasing the size of your codebase.

最终幸福 2024-07-31 04:19:55

复制/粘贴会导致不同的功能。 代码一开始可能是相同的,但随着时间的推移,一个副本中的更改不会反映在所有其他副本中应有的位置。

此外,在非常简单的情况下,复制/粘贴可能看起来“没问题”,但它也开始让程序员陷入复制/粘贴很好的心态。 这就是“滑坡”。 当重构应该是正确的方法时,程序员开始使用复制/粘贴。 您始终必须小心谨慎地设定先例以及向未来的开发人员发送哪些信号。

甚至有比我更有经验的人引用过这句话:

“如果您在编码时使用复制和粘贴,则可能会犯设计错误。”
——大卫·帕纳斯

Copy/Paste leads to divergent functionality. The code may start out the same but over time, changes in one copy don't get reflected in all the other copies where it should.

Also, copy/paste may seem "OK" in very simple cases but it also starts putting programmers into a mindset where copy/paste is fine. That's the "slippery slope". Programmers start using copy/paste when refactoring should be the right approach. You always have to be careful about setting precedent and what signals that sends to future developers.

There's even a quote about this from someone with more experience than I,

"If you use copy and paste while you're coding, you're probably committing a design error."
-- David Parnas

意中人 2024-07-31 04:19:55

您应该编写单元测试,虽然是的,克隆代码在某种意义上可以给您一种安全感,即您的更改不会影响大量其他例程,但这可能是一种错误的安全感。 基本上,您的安全感来自于对代码如何使用的无知。 (这里的无知不是贬义词,只是因为无法了解代码库的所有内容而导致的)习惯使用 IDE 来了解代码的使用位置,并习惯于阅读代码以了解如何使用它正在被使用。

You should be writing unit tests, and while yes, having cloned code can in some sense give you the sense of security that your change isn't effecting a large number of other routines, it is probably a false sense of security. Basically, your sense of security comes from an ignorance of knowing how the code is used. (ignorance here isn't a pejorative, just comes from as a result of not being able to know everything about the codebase) Get used to using your IDE to learn where the code is being use, and get used to reading code to know how it is being used.

淑女气质 2024-07-31 04:19:55

你写的地方:

重用的问题可能是
改变重用的代码会影响
许多其他功能。
...在某些情况下,似乎
复制/粘贴更好 - 每个用户
粘贴的代码有一个私人副本
它可以自定义,无需
后果。

我认为您已经消除了与复制粘贴相关的担忧。 如果您将代码复制到 10 个位置,然后需要对行为进行轻微修改,您会记得在所有 10 个位置进行更改吗?

不幸的是,我曾经研究过大量大而杂乱的代码库,通常您会看到的结果是相同的 4 行代码的 20 个版本。 其中一些(通常很小)子集有 1 个小更改,其他一些小(并且仅部分相交的子集)有一些其他小更改,不是因为变化是正确的,而是因为代码被复制和粘贴了 20 次,并且几乎应用了更改,但并不十分一致。

当事情发展到这一点时,几乎不可能分辨出哪些变化是有原因的,哪些变化是由于错误而存在的(而且因为它更常见的是疏忽的错误 - 忘记应用补丁而不是改变某些东西 - 有不太可能是任何证据或评论)。

如果您需要不同的功能,请调用不同的函数。 如果您需要相同的功能,请避免复制粘贴,以保证关注您的人的理智。

Where you write:

The problem with reuse can be that
changing the reused code will affect
many other pieces of functionality.
... In some cases it would seem that
copy/paste is better - each user of
the pasted code has a private copy
which it can customize without
consequences.

I think you've reversed the concerns related to copy-paste. If you copy code to 10 places and then need to make a slight modification to behavior, will you remember to change it in all 10 places?

I've worked on an unfortunately large number of big, sloppy codebases and generally what you'll see is the results of this - 20 versions of the same 4 lines of code. Some (usually small) subset of them have 1 minor change, some other small (and only partially intersecting subset) have some other minor change, not because the variations are correct but because the code was copied and pasted 20 times and changes were applied almost, but not quite consistently.

When it gets to that point it's nearly impossible to tell which of those variations are there for a reason and which are there because of a mistake (and since it's more often a mistake of omission - forgetting to apply a patch rather than altering something - there's not likely to be any evidence or comments).

If you need different functionality call a different function. If you need the same functionality, please avoid copy paste for the sanity of those who will follow you.

_蜘蛛 2024-07-31 04:19:55

有一些指标可用于衡量您的代码,并且由您(或您的开发团队)决定适当的阈值。 Ruby on Rails 有“Metric-Fu” Gem,其中包含许多可以帮助您重构的工具您的代码并使其保持最佳状态。

我不确定有哪些工具可用于其他语言,但我相信有一个适用于 .NET 的工具。

There are metrics that can be used to measure your code, and it's up to yo (or your development team) to decide on an adequate threshold. Ruby on Rails has the "Metric-Fu" Gem, which incorporates many tools that can help you refactor your code and keep it in tip top shape.

I'm not sure what tools are available for other laguages, but I believe there is one for .NET.

悍妇囚夫 2024-07-31 04:19:55

一般来说,复制和粘贴是一个坏主意。 然而,就像任何规则一样,这也有例外。 由于例外情况不像规则那样广为人知,我将重点介绍一些重要的情况:

  1. 恕我直言,您有一个非常简单的设计,您不想使用设计模式和面向对象的东西使其变得更加复杂。 你有两三个案例,它们的变化有无数种微妙的方式,即这里一条线,那里一条线。 从问题的本质来看,您的案例不可能超过 2 或 3 个。 有时,仅仅剪切和粘贴比彻底设计解决这样一个相对简单的问题可能是两害相权取其轻。 代码量是有成本的,但概念复杂性也是有成本的。

  2. 您现在有一些非常相似的代码,但是该项目正在快速发展,并且您预计这两个实例将随着时间的推移而出现显着差异,甚至会尝试识别相当大的实例,可分解的功能块将保持通用,更不用说将它们重构为可重用的组件,这将带来更多的麻烦而不是其价值。 当您认为对一个实例进行不同更改的可能性远大于对通用功能进行更改的可能性时,这一点适用。

In general, copy and paste is a bad idea. However, like any rule, this has exceptions. Since the exceptions are less well-known than the rule I'll highlight what IMHO are some important ones:

  1. You have a very simple design for something that you do not want to make more complicated with design patterns and OO stuff. You have two or three cases that vary in about a zillion subtle ways, i.e. a line here, a line there. You know from the nature of the problem that you won't likely ever have more than 2 or 3 cases. Sometimes it can be the lesser of two evils to just cut and paste than to engineer the hell out of the thing to solve a relatively simple problem like this. Code volume has its costs, but so does conceptual complexity.

  2. You have some code that's very similar for now, but the project is rapidly evolving and you anticipate that the two instances will diverge significantly over time, to the point where trying to even identify reasonably large, factorable chunks of functionality that will stay common, let alone refactor these into reusable components, would be more trouble than it's worth. This applies when you believe that the probability of a divergent change to one instance is much greater than that of a change to common functionality.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文