【问题标题】:What is the formal design pattern behind "monkeypatching"?“monkeypatching”背后的正式设计模式是什么?
【发布时间】:2010-12-22 15:11:00
【问题描述】:
此处的核心 CS 问题:在 Gamma 等中列出的设计模式中,哪些(如果有)涵盖了猴子补丁?此外,对于哪类问题,monkeypatching 与子类化比较合适?修补核心库类中的错误是其中之一,还有其他的吗?我听到很多关于stackoverflow上的monkeypatching的喧嚣,你们中的大多数人似乎对此有强烈的疑虑,但作为一名程序员,我真的很喜欢封装通用功能位并将它们包含在rails中的对象模型中的能力。
以thoughtbot-paperclip 为例,我为什么要对它进行子类化,而不是现在存在的monkeypatch 方法?
谢谢,
-埃里克
【问题讨论】:
标签:
jquery
ruby-on-rails
monkeypatching
【解决方案1】:
我不认为猴子补丁是一种设计模式——核心类扩展是一种他们似乎忽略的语言特性。
关于其他的,看看 Jeff Atwood 对this article on his blog 的看法。
在他(和我)的意见中,monkeypatching 的最大问题是,如果它修改现有方法,它会使调试变得非常困难 - 我们人类无法跟踪所有“这里和那里的小 sn-ps”,因为和机器一样。子类建立更清晰的分离。
所以我个人的猴子补丁规则是:
- 如果您可以不使用monkeypatching 并且它可以正常工作,请不要使用monkeypatching。
- 您可以向类添加新方法,但不能修改现有方法。
- 以一种非常明显和明显的方式进行 - 即在 /lib 中的一个名为 string_extensions.rb 的文件,而不是在隐藏的 /myvendor/submodule/se.rb 中。
- 应该是本地的;不使用库的类应该不受影响。
现在,举个例子:回形针。
- 据我所知,它会将方法添加到您的 ActiveRecord 类中,但不会修改现有方法
- 必须在使用回形针的类中添加
has_attachment 指令,否则不受影响。
因此更改是本地化且明显的(我实际上认为它设法改进调试:我们人类更容易阅读has_attachment而不是class MyModel < Paperclip::ActiveRecordWithAttachment)。
在这种情况下,子类化也是一个坏主意,因为除了另一个使用子类的插件之外,您将无法使用回形针 - rails 是单一继承的。
在 Paperclip 的案例中,它显然是与附件的 has_a 关系,而不是 is_a 关系。有人可能会争辩说,这不是对子类化的正确使用。
最后,我想指出的是,Paperclip 在某些情况下需要子类化(您必须使用子类化才能创建回形针处理器)。