基于对象类的控制流/条件基础设计是不是很糟糕?

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

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

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

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

如果它完全没问题,那么人们何时可能想要特别使用它?

谢谢!

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

 object.is_a? Foo 

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

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

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

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

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

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

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