首先,这实际上是否违反了封装的 OO 原则?
是的。
其次,作为一名程序员,有没有办法可以在我的代码中保证我正在使用一个未修改版本的类?
还没有。Ruby 2.0 中的 Classboxes(希望)将成为解决方案。
第三,出于任何原因,我是否应该在我的代码中“打开”类?
只能作为最后的手段。
您永远不应该对自己的课程进行修补。根本没有意义。你控制他们,你可以让他们首先做你想做的事。
您永远不应该在库中修补类。(这个规则的例外是那些唯一目的是对某些东西进行猴子补丁的库,例如 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
. 它应该是完全可选的。
你不应该猴子补丁核心类。这指的是RubyArray
或Ruby 中的类,但对于 Rails 库,我还会在“核心”标签下Symbol
包含类。ActiveRecord::Base
(与上述相同的警告。例如,在 3.0 之前的 Rails 版本中,没有明确定义的插件 API,猴子补丁是扩展 Rails 的唯一方法。如果没有人违反这条规则,就不会有任何插件,并且Rails 永远不会像现在这样。)
先试试继承。首先尝试组合(包装器、代理、外观、适配器……)。先尝试重构。首先尝试辅助对象。只有当这不起作用时,才转向猴子补丁。
当你打猴子补丁时要尊重:如果你正在添加一个新方法,请确保它不存在,如果存在则处理它(例如,从你的方法中调用它)。如果您要包装现有方法,请确保如果其他人已经包装了它,他们的包装器会被调用,并且当有人想在之后包装它时,您的包装器允许这样做。(特别是,这意味着您必须保留该方法的现有合同。)
如果可能的话,把你的猴子补丁放在一个 mixin 中。这样,它们就会出现在继承链中,这将使任何尝试调试代码的人都有机会弄清楚发生了什么。将你的猴子补丁放在单独的、明显命名的文件中。
最后,在大规模的生产编码环境中如何处理这类事情?换句话说,编程行业的人真的会在其他人会使用的代码中这样做吗?或者即使他们不这样做,您如何确保某处的某个插件作者没有做这样的事情会破坏您程序的重要部分?
不要与你所说的“非常糟糕的程序员”一起工作。
听起来很简单,但基本上就是这样。是的,当然,您可以编写测试、进行代码审查、练习结对编程、使用静态分析工具、在启用警告的情况下运行您的代码(例如,您在问题中发布的代码将生成一个warning: method redefined; discarding old ==
. 但对我来说,这都是一个不是很差的程序员无论如何都会做的事情。