围绕一个对象的类控制流/条件是不好的设计?

时间:2011-11-21 07:31:51

标签: ruby-on-rails oop

我目前正在开发一个Rails项目,并找到了最容易做到的时间

if object.class == Foo
  ...
else if object.class == Bar
  ...
else
  ...

我开始在视图中执行此操作,我需要以不同的方式显示不同的对象,但现在发现自己在其他地方使用它,例如在将对象作为参数的函数中。我不确定为什么,但我觉得这不是好习惯。

如果这不是好习惯,为什么呢?

如果它完全没问题,那么人们可能想要专门使用它的时间是什么时候?

谢谢!

3 个答案:

答案 0 :(得分:3)

不确定为什么它对你有用。当您需要测试object是否是类Foo的实例时,您应该使用

object.is_a? Foo

但无论如何,这在Ruby中并不是一个好习惯。只要有可能,最好使用多态。例如,如果代码中的某个位置可以包含两个不同类的对象,并且需要以不同方式显示它们,则可以在两个类中定义display方法。之后,您可以调用object.display,并使用相应类中定义的方法显示对象。

这种方法的优点是,当你需要为第三类或一大堆新类添加支持时,你需要做的就是在每一个中定义display方法。但是在实际使用此方法的地方没有任何改变。

答案 1 :(得分:2)

最好使用子类型表达特定于类型的行为。 让对象知道它们是如何显示的。创建方法Display()并从外部传递您需要的所有参数。让“Foo”知道显示foo,“Bar”知道如何显示条形。

有很多关于用多态性替换条件的文章。

答案 2 :(得分:2)

出于几个原因,这不是一个好主意。其中一个是duck typing - 一旦你开始在代码中显式检查对象类,你就不能再简单地传递一个符合与原始对象类似的接口的不同类的实例。这使代理,模拟和其他常见的设计技巧更难。 (这一点也可以概括为打破封装。可以认为对象的类是一个实现细节,你作为消费者不应该感兴趣。破解封装≈紧耦合≈痛苦。)

另一个原因是可扩展性。当您对对象类型进行巨大切换并想要再添加一个案例时,您必须更改开关代码。例如,如果此代码嵌入到库中,则库用户不能简单地扩展库的行为而不改变库代码。理想情况下,对象的所有行为都应该是对象本身的一部分,这样您就可以通过添加更多对象类型来添加新行为。

如果你需要以不同的方式显示不同的对象,你不能简单地将绘图代码作为对象的一部分吗?