OOP组织问题的最佳解决方案

时间:2011-12-21 21:05:10

标签: oop class organization

我有一个关于特定OOP问题组织的快速问题。

说我有一个Terrain类,里面装满了Tiles。 Tile类有多种衍生物,即Door。 Door类有一个名为open()的方法,它打开门,关闭()关闭门。这非常有意义,直到这两种方法都需要在打开和/或关闭之前检查某些方法。如何在不知道其父对象的情况下对某个对象进行检查?

一个简单的解决方案是在调用open()之前检查某些方法,但如果有一种不同类型的门需要检查不同的形状,则会在更高级别上造成混乱。

这似乎有一个简单的答案,但似乎我经常遇到这个问题。

1 个答案:

答案 0 :(得分:2)

一个答案是,门应该知道如何打开和关闭自己,并知道它们是否被阻止。如果Door是一个类,那么状态( is_open is_blocked )和行为( open_the_door close_the_door )应该驻留在Door类中。封装是面向对象范式的基本原则。

但现实世界的答案通常更为微妙。您能提供一些有关应用程序的背景知识以及它需要完成的工作吗?有一些干净,简单的解决方案适用于玩具应用,但更大的应用程序需要更复杂的东西。

如何处理门 is_blocked 提出了一些设计问题。没有一个正确的设计,但有良好的设计和糟糕的设计。将好的想法与坏的想法分开取决于不仅仅是设计原则 - 它取决于问题的背景。

如果我不得不猜测,我猜你的应用程序就是游戏。也许瓷砖代表游戏板或地图的区域。您已经确定许多不同的对象可能需要进行交互,如果它们都直接相互引用,那么它将会很混乱。

  • 游戏通常有一个名为“游戏”或“棋盘”或“地图”的主对象。让主对象保存Tile层次结构中的东西集合(tile,door等)。

  • 让主对象也收藏可以阻挡门或以其他方式与瓷砖和门相互作用的东西。

  • 现在在Tile类上创建一个名为update()的方法,该方法接受一个对象作为参数。

  • 并为Door类创建一个名为“blocked”的布尔属性。 门的更新方法可能会这样:

    Door::update(BlockingObject object) {
     if(object.location == this.location)
          blocked = true 
     }

  • 门的超类方法可能什么都不做。像这样:

    Tile::update(BlockingObject obj) {
         //tiles cannot be blocked
    }

  • 现在,在游戏循环中,包含一个步骤,其中所有门都设置为blocked = false

  • 创建一些循环要求所有磁贴检查它们是否被阻止。它可能在伪代码中看起来像这样:

    For each tile {
         For each blocking object {
              tile.update(object)
         }
    }

  • 这是一个天真,但直截了当的设计,适用于OO范例。

  • 该设计使得瓷砖/门和物体有机会每回合交互一次,而不会强迫它们彼此保持参照。

  • 这个设计适用于几百个瓷砖和物体,但对于数千个瓷砖来说它会变得很慢。

这是一个好的设计吗?

答案取决于应用程序的需求。