Ruby的“开放类”是否破解封装?

前端之家收集整理的这篇文章主要介绍了Ruby的“开放类”是否破解封装?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Ruby中,程序员可以更改预定义的类.所以一个非常糟糕的程序员可以做一些事情:
class String
  def ==(other)
    return true
  end
end

显然,几乎没有人会这么愚蠢,但是对于一个预定义的类来说,更微妙的变化可能会导致已经在工作的代码中出现问题的想法似乎违反了封装的原则.

四个问题:

>首先,这是否实际上违反了OO的封装原理?
>第二,有办法,作为程序员,我可以保证
我的代码,我正在使用一个未修改的类的版本?
>第三,我应该在我的代码中为任何“开放”类
原因?
>最后,在大规模生产编码环境中如何处理这种事情?换句话说,编程行业的人们实际上是以别人的代码来做到这一点
将使用?或者即使没有,你如何确保一些
插件作者在某处没有做这样的事情
会毁坏你节目的重要部分?

我知道这是一个有点主观的问题,但我真的很想知道更广泛的编程社区对这个所谓的“猴子补丁”的感受.

解决方法

First,does this,in fact,violate the OO principle of encapsulation?

是.

Second,is there a way,as a programmer,that I can guarantee in my code that I am working with an unmodified version of a class?

还没. (希望)Ruby 2.0中的类框将成为解决方案.

Third,should I ever be “opening” classes in my code,for any reason?

只能作为最后的手段.

你不应该猴子补丁你自己的课程.根本没有意义.你控制他们,你可以让他们做你想要的首先.

你不应该在一个图书馆里猴子修补课程. (这个规则的例外是图书馆,其唯一的目的是为了补充某些东西,例如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方法),但该加载项应该在一个单独的库中,用户需要明确要求.它应该是完全可选的.

你不应该是猴子补丁核心课程.这指Ruby中的Array或Symbol类,但是对于Rails库,我还将在“core”标签下包含类ActiveRecord :: Base. (与上述相同的注意事项,例如3.0版之前的Rails版本,没有明确的插件API,猴子修补是扩展Rails的唯一方法,没有人打破这个规则,永远不会有任何插件,Rails永远不会在那里.)

先尝试继承.首先尝试组合(包装,代理,外观,适配器,…).尝试重构.先尝试帮助对象.只有这样不起作用,就转向猴子修补.

当猴子补丁时,请尊重:如果您添加了一种新方法,请确保它不存在,并处理它(例如从您的方法调用).如果您正在包装现有的方法,请确保如果其他人已经包装好了,那么它们的包装器将被调用,而当有人想要包装它时,您的包装器允许这样做. (特别是这意味着您必须保留该方法的现有合同.)

如果可能的话,将你的猴子补丁放在一个混合物中.这样,他们就会出现在继承链中,这将给任何人试图调试代码一个战斗机会来弄清楚发生了什么.将您的猴子补丁放在单独的,明显命名的文件中.

Finally,how is this sort of thing handled in a large-scale,production coding environment? In other words,do people in the programming industry actually do this in code that others will use? Or even if they don’t,how do you ensure that some plugin author somewhere isn’t doing something like this that will ruin an essential part of your program?

不要和“真坏的程序员”一起工作,就像你所说的那样.

就像这听起来那样简单,这基本上是归结到的.是的,当然,你可以编写测试,做代码评估,练习配对编程,使用静态分析工具,运行您的代码,启用警告(例如您在问题中发布的代码将会产生一个警告:重新定义方法;废弃旧== ).但是对于我来说,这一切都是一个不太糟糕的程序员会做的.

猜你在找的Ruby相关文章