这里的核心 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
发布评论
评论(1)
我不认为猴子补丁是一种设计模式 - 核心类扩展是他们似乎忽略的语言功能。
关于其余部分,请查看 Jeff Atwood 对他博客上的这篇文章的看法。
在他(和我)看来,monkeypatching 的最大问题是,如果它修改了现有方法,它会使调试变得非常困难 - 我们人类无法像机器那样跟踪所有“这里和那里的小片段”。子类建立了更清晰的分离。
所以我个人对monkeypatching的规则是:
现在,以您的示例:回形针。
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:
Now, to your example: Paperclip.
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 ofclass 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 ais_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).