在用户交互方面,OO vs Simplicity

时间:2010-05-18 22:04:45

标签: java oop

作为一个夏季的项目,当我从Uni有一些停机时间我将建立一个垄断游戏。这个问题更多的是关于问题的一般概念,而不是我正在尝试执行的具体任务。

我决定采用自下而上的方法来构建它,在四十个空间板周围创建运动,然后继续与空间交互。我意识到我完全不确定如何处理这个问题,而且我在两个设计理念之间徘徊:

  1. 为每个空间提供自己的对象,空间对象的所有子类,以便空间对象本身可以定义交互。我可以通过为每种类型的空间实现不同的land()方法来实现这一点。

  2. 只提供Properties和Utilities(因为每个属性都有独特的功能)对象,并创建方法来处理程序主类(或我称之为Board)中的购买/租赁等。像go和super tax这样的空间可以通过一小组条件来实现,以检查玩家是否在一个特殊的空间。

  3. 选项1显然是OO(我认为是正确的)做事方式,但我只想处理来自程序主类的用户交互。换句话说,我不希望空间物体与玩家交互。 为什么? Errr。到目前为止,我所做的很多编码都具有这种简单性,但我不确定这对于大型项目是否是一个梦想。我真的应该在一个完全独立的类中处理用户交互吗?

    你可以看到我对这种情况很困惑。这有什么办法吗?并且,有没有人对实际的OO设计有任何建议可以帮助一般?

    编辑:请注意我觉得我对这个问题失去了一点关注。我对组合OO和任何外部操作(命令行,网络,GUI,文件管理等)的一般方法感兴趣。

7 个答案:

答案 0 :(得分:5)

我同意选项#1似乎更好。

至于“用户互动” - 一切都取决于。您可以将一些代码留在另一个类中。例如,

// in main class
user.landOn(space);
if (space.containsProperties()) doSomething(); // Option #1 for some user-interaction code

// in User.java
public void landOn(Space s) {
    // do some checks
    s.land(this);
    if (s.containsProperties()) {...} // Option #2
    // something else?
}

// in GetMoneySpace.java
@Override
public void land(User u) {
    u.awardCash(200);
    // Option #3 - no properties so nothing here
}

这比其他类似的东西(在我看来更好)(

if (space.isCashAwardSpace()) {
    user.awardCash(space.getAward());
}
if (user.something()) doSomething(); // Some user-interaction code

答案 1 :(得分:5)

最后,这取决于你。这是OO的美丽,因为它需要解释。通常应该遵循一些模式,但一般来说,您决定如何处理它。

但是,你应该仔细考虑系统中每个参与者应该知道的其余部分。财产应该真正了解玩家,他的账户余额以及其他玩家吗?可能不是。物业应该知道它的成本,租金是多少等等。

另一方面,主要播放线程是否应关注支付租金等微不足道的事情?可能不是。其主要关注点应该是游戏本身的状态,例如骰子滚动,每个玩家是想交易还是购买还是非抵押/抵押等等。

想一想在广场上降落的动作。登陆后,玩家有3种选择:

  • 购买房产
  • 忽略该属性
  • 支付租金

现在,系统中的哪个actor知道完成该操作所需的所有信息。我们有Game类,它不关心这种单调乏味。我们拥有该物业,并不真正关心球员。但是Player对象知道所有这些信息。它记录每个玩家拥有的内容,并可以轻松访问正确的数据。

所以,如果是我,我会制作一个Player.performMove(Die d)方法。它可以轻松访问帐户。这也允许类之间的耦合最少。

但最终,这取决于你。我相信人们已经用完美的OO以及功能或程序语言创建了Monopoly克隆。最后,使用你所知道的并继续重构,直到你对最终设计感到满意为止。

答案 2 :(得分:1)

选择第一个设计。您将拥有一个Property类,并对特殊属性进行子类化,从而覆盖默认行为。

就交互而言,您可以拥有一个Token类,并在棋盘周围移动一个实例。您必须为用户提供一些选项,但是,从响应中,您应该调用对象上的方法,而不是在用户事件中放置复杂的逻辑。

示例类:

  • 属性
    • 名称
    • baseRent
    • houseCount
    • hotelCount
    • 抵押
    • getCurrentRent()
  • RailRoad扩展物业
  • Utility extends Property
    • 属性
  • 用户
    • 令牌
    • playerName
    • currentProperty
    • ownedProperties
    • buyProperty()
    • payRentOnProperty()
    • mortgageProperty()
    • 移动()

答案 3 :(得分:1)

我不完全确定我是否理解正确。在设计软件时,您始终有这样的选择。我个人会选择第一个选择。一个论点是小游戏(Scrabble)的个人经验,这让我觉得好的设计也适用于小型项目。 OOP的重点在于,您可以对您的设计有不同的看法,并获得一些设计优势。例如,想象一下添加新字段,更改现有字段,重用多个字段中一个字段的行为是多么困难。

答案 4 :(得分:1)

你的第一个方法是我要去的方法。它将行为封装在需要的地方。因此,你有实用程序,属性,GotoJail,FreeParking的Space子类 - 基本上所有不同的空间类别。对类别进行分组的是它的常见行为。

您的属性空间本身可能有一个组对象作为成员,例如将所有深蓝色属性组合在一起。

关于与用户的交互,您将Board(或更好的GameController)实例传递给每个空间,因此它知道它所属的游戏并且可以影响游戏。然后,Space可以在棋盘上调用特定的动作,例如,移动棋子,向用户询问问题等。主要观点是存在分离 - 用户交互不在每个空间内发生 - 但允许空间要求发生一些交互,或者移动一块。这取决于您的GameController实际进行交互或移动棋子等。这种分离使其易于测试,并根据需要提供替代实施(例如,不同版本/国家/地区的不同游戏规则?)

答案 5 :(得分:0)

选项2没有多大意义,或者至少它不像选项1那样清晰。对于选项1,您不需要 来处理空间对象内的用户交互。您可以在主类或专用于处理用户交互的单独类中使用:

public void move(Player p, int spaces){
    Space landingSpace = board.getLandingSpace(p,spaces);
    landingSpace.land(p); //apply your logic here
}

如您所见,Space类负责检查打算在该空间上着陆的Player p。它应用任何自定义逻辑,检查它是否有足够的钱,如果它是玩家拥有的东西等等。Space的每个子类都有自己的一套规则,如选项1中所述。

答案 6 :(得分:0)

面向对象设计的部分要点是简化解决方案空间内问题的表示(即,在计算机中对系统进行建模)。在这种情况下,请考虑对象之间的关系。 Space中是否有足够的功能来保证将其抽象为一个类,或者是否因为存在与Property无关的离散UtilitySpace类更有意义,因为两者的独特功能? PropertySpace的一种特殊类型,还是Space中的一个字段?这些是你在设计游戏时可能需要解决的问题。

就交互而言,当你有一个'god class'完成所有工作并且只是向其他类提供信息时,对于一个设计来说通常是坏消息。有很多方法可以陷入这个陷阱;确定您是否正在处理神班的一种方法是查找包括ManagerSystem的班级名称。因此,拥有某种“游戏管理器”可能不是最好的想法,它会向所有其他对象询问数据,进行所有更改并跟踪所有内容。尽可能地消除这些。

上帝阶级违反了encapsulation的概念,它涉及的不仅仅是数据隐藏(尽管这肯定是其中很重要的一部分)。良好的封装意味着相关的方法和数据是单个对象的一部分。例如,属性不需要向其所有者发出请求,因此包含对Player的引用的字段可能违反封装。其中一些封装违规行为根本不明显,很难发现。在设计对象时,尝试确定有关需要与外部对象共享的对象的最小信息量。修剪任何不必要的东西。

显然你可以通过很多方式解决这个问题,但我的设计会是这样的(迭代肯定会证明它错了):

  • Space类,包含所有空格共有的基本数据和方法(例如它们在板上的位置,是否占用等)。
  • 子类从最常见的(PropertyUtility)移动到最独特的(GoJailFreeParking等等;可能是单身人士)与每个相关的字段和方法。
  • Player类包含玩家信息。
  • GameState关注游戏状态的课程;轮到它了,银行里还剩下多少房子,等等。

祝你好运,继续学习。

当然,谷歌是你的朋友,但这里有一些我建议读的东西: