【发布时间】:2021-08-09 14:31:50
【问题描述】:
出于教育目的,我正在尝试在 C# 控制台中创建纸牌游戏“大富翁交易”的副本。我的班级设计有一个问题,我不知道如何解决。我有两个班级,Game 和 Player。 Game 控制游戏的状态,并包含Player 对象的列表。
目前它的工作方式是Game 类控制一切。 Player 基本上是一个容器类:它包含玩家收藏中的所有卡片。决策由Game 类完成,因为它可以看到所有玩家,因此知道哪些动作是可能的。
例如,如果玩家 1 想从玩家 2 那里偷一张牌,我的程序必须首先验证玩家 2 是否有任何牌可以偷。玩家 1 不知道这一点,因为它只是 Player 对象列表中的一个对象。所以Game 类有一个方法可以检查玩家可以做出的所有可能的动作,要求玩家选择他们想要做出的动作,然后为他们执行那个动作。
我的问题:我认为这不是好的 OOP 类设计。我认为我应该将决策委托给 Player 类,而不是 Game 类 - 否则我的 Game 类将变得臃肿,其中包含许多与玩家行为和决策相关的方法,而不是游戏陈述自己。但是,我不知道如何实现这一点。
可能的解决方案:
- 创建一个
GameState对象,其中仅包含其他玩家卡片的有限视图,并将其传递给Player对象(似乎是最简单的方法,但我想它会创建冗余数据,这是浪费内存。) - 将整个
Game对象的引用传递给Player类(我可以这样做 - 这不像我要通过 ComputerPlayers 编写程序来作弊 - 但感觉也不是好的 OOP 设计) - 放弃,将所有游戏逻辑(包括计算机 AI)放在
Game类中,并接受Player只是一个数据容器,而不是决策者。 - 以不同的方式重新设计我的课程。
- 我还错过了什么?
这里有什么明显的解决方案吗?谢谢。
编辑:我试图减少问题中的过多细节,因为它因“焦点不足”而关闭。如果需要进一步修改,请告诉我。
【问题讨论】:
-
这是一个很长很宽泛的问题。对于这个in the Top 5 recurrent question,你可以根据你的needs or opinion使用:单例、静态数据成员、事件、静态运行方法模式、带参数的构造函数、组合、聚合等等……
-
一般来说,我们经常尝试区分包含应用程序逻辑的类和表示数据的类。因此,如果您有一个代表玩家的 Player 类,我不会在其中嵌入任何实际逻辑,只是足以初始化玩家的属性并维护玩家的外部状态。
-
这篇文章几分钟内产生的(长)cmets 的数量清楚地表明这是一个讨论而不是问答。 (在我看来,这似乎表明评论者也不真正知道 SO 应该如何工作;但这是一个单独的问题。)理想情况下,关于 SO 的问题应该导致一个清晰而正确的答案。不是推荐,不是最佳答案,而是正确答案。这个问题没有单一的正确答案,因此其他答案将是不正确的。这仍然是一个很好的问题;但是对于讨论论坛而不是SO。很好的问题,错误的地点。
标签: c# class oop console-application class-design