“monkeypatching”背后的正式设计模式是什么?

发布于 2024-08-13 09:52:32 字数 285 浏览 6 评论 0 原文

这里的核心 CS 问题:Gamma 等中列出的设计模式中,哪些(如果有)涵盖了猴子补丁?此外,猴子补丁与子类化适合什么类型的问题?修补核心库类中的错误是其中之一,还有其他吗?我在 stackoverflow 上听到了很多关于 Monkeypatching 的争论,大多数人似乎对此抱有强烈的疑虑,但作为一名程序员,我真的很喜欢封装通用功能并将它们包含在 Rails 中的对象模型中的能力。

以thoughtbot-paperclip为例,为什么我想要将其子类化,而不是当今存在的monkeypatch方法?

谢谢, -埃里克

Core CS question here: of the Design Patterns listed in Gamma, etc, which (if any) cover monkeypatching? Additionally, for what class of problems is monkeypatching appropriate vs. subclassing? Patching bugs in core library classes is one, are there others? I hear lots of sturm und drang about monkeypatching on stackoverflow, most of you seem to have strong misgivings about it, but as a programmer I really like the ability to encapsulate generic bits of functionality and include them in my object models in rails.

Take thoughtbot-paperclip, for example, why would I want ever want to subclass that vs the monkeypatch approach that exists today?

Thanks,
-Eric

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

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

发布评论

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

评论(1

折戟 2024-08-20 09:52:32

我不认为猴子补丁是一种设计模式 - 核心类扩展是他们似乎忽略的语言功能。

关于其余部分,请查看 Jeff Atwood 对他博客上的这篇文章的看法。

在他(和我)看来,monkeypatching 的最大问题是,如果它修改了现有方法,它会使调试变得非常困难 - 我们人类无法像机器那样跟踪所有“这里和那里的小片段”。子类建立了更清晰的分离。

所以我个人对monkeypatching的规则是:

  • 如果你可以在不使用monkeypatching的情况下完成它并且它可以正常工作,那么就不要使用monkeypatching。
  • 您可以向类添加新方法,但不能修改现有方法。
  • 以非常明显且明显的方式进行 - 即 /lib 中名为 string_extensions.rb 的文件,而不是隐藏的 /myvendor/submodule/se.rb 。
  • 应该是本地的;不使用库的类应该不受影响。

现在,以您的示例:回形针。

  • 据我所知,它向您的 ActiveRecord 类添加了方法,但不会修改现有的方法。
  • 您必须向使用回形针的类添加一个 has_attachment 指令,否则它们不会受到影响。

因此,这些更改是本地化的且显而易见的(我实际上认为它设法改进调试:对于我们人类来说更容易阅读 has_attachment 而不是 class MyModel )。

在这种情况下,子类化也是一个坏主意,因为除了另一个使用子类的插件之外,您将无法使用回形针 - Rails 是单继承的。

在 Paperclip 的例子中,它与其附件显然是一种 has_a 关系,而不是 is_a 关系。有人可能会说这不是子类化的正确使用。

最后,我想指出,Paperclip 在某些情况下需要子类化(您必须使用子类化才能创建回形针处理器)。

I don't think monkeypatching is a Design Pattern - core class extension a language feature that they seem to ignore.

Regarding the rest, have a look at Jeff Atwood's views on this article on his blog.

In his (and my) oppinion the biggest problem with monkeypatching is that it can make debugging very difficult, if it modifies existing methods - we humans can't keep track of all the "little snippets here and there" as well as machines do. Subclasses stablish clearer separations.

So my personal rules for monkeypatching are:

  • If you can do it without monkeypatching and it will work ok, don't use monkeypatching.
  • You can add new methods to classes, but you can't modify existing ones.
  • Do it in a very visible and obvious way - i.e. a file called string_extensions.rb in your /lib, not on a hidden /myvendor/submodule/se.rb .
  • Should be local; classes that don't use a library should be unaffected.

Now, to your example: Paperclip.

  • To my knowledge, it adds methods to your ActiveRecord classes, but doesn't modify existing ones
  • You have to add a has_attachment directive to the classes that use paperclip, otherwise they are not affected.

So the changes are localized and obvious (I actually think that it manages to improve debugging: is easier for us humans to read has_attachment instead of class MyModel < Paperclip::ActiveRecordWithAttachment).

Subclassing is also a bad idea on this case because you would not be able to use paperclip in addition to another plugin that used subclasses - rails is single-inherited.

And in Paperclip's case, it is clearly a has_a relationship with its attachment, not a is_a one. One could argue that it would not be a proper use of subclassing.

Finally, I'd like to point out that Paperclip requires subclassing in some occasions (you have to use subclassing in order to create a paperclip processor).

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