【问题标题】:Is it bad design to base control flow/conditionals around an object's class?围绕对象的类建立控制流/条件是不好的设计吗?
【发布时间】:2011-11-21 07:31:50
【问题描述】:

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

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

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

如果这不是好的做法,为什么会这样?

如果完全没问题,什么时候可以专门使用它?

谢谢!

【问题讨论】:

    标签: ruby-on-rails oop


    【解决方案1】:

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

    object.is_a? Foo
    

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

    这种方法的优点是,当您需要添加对第三个类或一大堆新类的支持时,您只需在每个类中定义 display 方法即可。但是在您实际使用此方法的地方,什么都不会改变。

    【讨论】:

    • to_s 将在从 object.class 返回的类名上调用,以尝试使类型兼容,因此它应该可以工作。 === 也将用于检查类型。 object === Foo
    • 在 1.8.7 和 1.9.2 中都试过了:object.class == A 工作正常(即使没有 ===),但 object.class == 'A' 不起作用。
    • 是的,我累了,不想加双引号。已编辑问题以供将来参考,感谢您的回答!
    【解决方案2】:

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

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

    【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 谢谢,你描述的点正是我的疑虑!我绝对同意你和 KL-7 的观点,即制作显示方法是最明智的做法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 2012-11-05
    • 2015-01-03
    相关资源
    最近更新 更多