首先,这是否违反了封装的面向对象原则?
是的。
其次,作为程序员,有没有一种方法可以在代码中保证我正在使用一个未修改的类版本?
目前还没有。Ruby 2.0 中的 Classboxes(希望如此)将是解决方案。
第三,我是否应该以任何理由“打开”类?
只有在万不得已的情况下才需要。
您绝对不应该猴子补丁(monkey-patch)您自己的类。这根本没必要。您能够控制它们,在一开始就可以让它们按照您的意愿运行。
您绝不应该猴子补丁库中的类。(唯一的例外是那些旨在进行猴子补丁的库,例如 Marc-André Lafortune 的 backports 库,它会在 Ruby 1.8.6、1.8.7、1.9.0 和 1.9.1 上进行猴子补丁,尽可能地提供来自 Ruby 1.9.2 的所有功能。)您可以提供一个附加库,其中包含一些猴子补丁,使使用您的库变得更加容易 (例如,您有一个加密库,可以提供一个 Kryptonite.encrypt(str) 方法和一个 String#encrypt 方法的附加库),但是该附加库应该是一个独立的库,用户需要明确地 require 它,并且应该是完全可选的。
不应该对核心类进行猴子补丁。这指的是 Ruby 中的 Array
或 Symbol
等类,但对于 Rails 库,我还会将诸如 ActiveRecord::Base
这样的类包括在“核心”标签下。(与上述相同警告。例如,在 3.0 版本之前的 Rails 中,没有明确定义的插件 API,猴子补丁是扩展 Rails 的唯一方法。如果没有违反此规则的人,就永远不会有任何插件,并且 Rails 永远不会达到现在的状态。)
首先尝试继承。首先尝试组合(包装器、代理、外观、适配器等)。首先尝试重构。首先尝试辅助对象。只有在这些方法都不起作用时,再考虑猴子补丁。
当进行猴子补丁时,请保持尊重:如果您正在添加新方法,请确保它不存在,并在出现时处理它(例如从您的方法中调用它)。如果您正在包装现有方法,请确保如果其他人已经包装它,则调用他们的包装器,并且当有人想要稍后再包装它时,您的包装器允许这样做。(特别是,这意味着您必须保留方法的现有约定。)
如果可能,请将猴子补丁放入混合组件中。这样,它们会在继承链中显示,这将为任何试图调试代码的人提供机会弄清发生了什么。将猴子补丁放入单独的、明显命名的文件中。
最后,在一个大规模的生产编码环境中如何处理这种情况?换句话说,程序员在实际使用其他人的代码时真的会这样做吗?或者即使他们不这样做,你如何确保某个插件作者没有做某些可能会破坏程序的重要部分的事情?
避免与“非常糟糕”的程序员合作。
尽管听起来简单,但这基本上就是要点。当然,您可以编写测试、进行代码审查、练习成对编程、使用静态分析工具、启用警告运行您的代码(例如,您在问题中发布的代码将生成一个warning:method redefined; discarding old ==
)。但对于我来说,这些都是一个不算太差的程序员会做的事情。