我不认为猴子补丁是一种设计模式——核心类扩展是一种他们似乎忽略的语言特性。
关于其余部分,请查看 Jeff Atwood在他的博客上对这篇文章的看法。
在他(和我)的意见中,monkeypatching 的最大问题是,如果它修改现有方法,它会使调试变得非常困难——我们人类无法像机器一样跟踪所有“这里和那里的小片段”。子类建立更清晰的分离。
所以我个人的猴子补丁规则是:
- 如果你可以在没有monkeypatching的情况下做到这一点并且它可以正常工作,请不要使用monkeypatching。
- 您可以向类添加新方法,但不能修改现有方法。
- 以非常明显和明显的方式进行 - 即 /lib 中名为 string_extensions.rb 的文件,而不是隐藏的 /myvendor/submodule/se.rb 。
- 应该是本地的;不使用库的类应该不受影响。
现在,以您的示例为例:回形针。
- 据我所知,它为您的 ActiveRecord 类添加了方法,但不会修改现有的
- 您必须向
has_attachment
使用回形针的类添加指令,否则它们不会受到影响。
所以这些变化是本地化的并且很明显(我实际上认为它设法改进了调试:我们人类更容易阅读has_attachment
而不是class MyModel < Paperclip::ActiveRecordWithAttachment
)。
在这种情况下,子类化也是一个坏主意,因为除了另一个使用子类的插件之外,您将无法使用回形针 - rails 是单继承的。
而在回形针的案例中,它显然has_a
与它的依恋关系,而不是一种关系is_a
。有人可能会争辩说,这不是对子类化的正确使用。
最后,我想指出,Paperclip 在某些情况下需要子类化(您必须使用子类化才能创建回形针处理器)。