我正在设计一个用Java的国际象棋游戏(没有人工智能,只有用户控制),并且仍然习惯于OOP。我有两个问题。
除了Game
,Cell
,Piece
和Board
个对象之外,我还想考虑一个Player
个对象。
我的问题是,我真的需要吗?当然我不需要,但是两种选择都被认为是更好的设计?一方面,似乎播放器对于包含有关玩家片段的信息很有用,并且应该包含takeTurn()
等方法。 (对于我的实现,我也想跟踪所有可能的移动,所以我将有一个方法getAllMoves()
)。另一方面,玩家不是简单地重组现有数据吗?每件作品都已经显示了它属于哪个玩家。由于我的游戏不包含AI,因此takeTurn()
属于Game
而不是Player
可能是有意义的。再一次,也许Player
只能使用getAllMoves()
方法,该方法使用其数据但不采取行动。
第二个问题,如果第一个问题的答案是肯定的,那么我如何组织对象之间的关系? getAllMoves()
将输入一组单元格作为输入;但令人感到奇怪的是,Player类依赖于它的单元格与作为输入传入的单元格匹配(是其子集)的事实。如果将细胞分割的细胞数据与Board中所有细胞的阵列保持在一起并一起更新,从而保证它们一致,那就更好了。当然,他们同意的保证会以任何一种方式存在,但似乎Player对象不应该知道Board
对象中发生的保证。
我如何处理这些问题?
谢谢!
答案 0 :(得分:2)
拥有Player对象的恕我直言是一个很好的设计 您甚至可以稍后将其改进为具有AIPlayer和HumanPlayer实现的接口 今天你只需要getAllMoves方法,但稍后你可能需要更多。拥有一个对象可以帮助你扩展你的玩家的能力。
对于你的第二点,我不确定Player应该直接实现getAllMoves()方法。
我会将其委托给ChessGame对象。在这种情况下,播放器将引用游戏并将getAllMoves调用委托给此Game实例,如下所示:
伪代码:)
嘿,游戏,这件作品的可用动作是什么?
答案 1 :(得分:1)
是否需要“播放器”对象的问题 - 问问自己这个对象是否与系统中的其他对象有任何交互/关系。此外,它是否有您可能想要记录的任何数据或状态信息?我可以想到你可能希望跟踪与玩家相关的一些事情 - 捕获的碎片,也许是得分。
顺便说一句,构建一个对象模型以可视化对象如何相互关联可能是个好主意。这也可以让您更好地了解对象之间的接口以及所需的方法。
答案 2 :(得分:1)
您熟悉UML,更具体地说是用例和序列图吗?这听起来像是模型化中的一个练习,同时查找域模型的概念也是一个好主意。
像Player一样的Use Case actor通常被转换为类(也就是替代)。其他类可以通过以每个用例的粗略序列图开始,一方面是Actor类,另一方面是全局System类。
当您浏览不同的消息时,可以逐步分解此System类。如果方法/消息不直接属于类的单个实例,并且它的属性/内部状态很可能属于其他地方(例如:BankAccount类与BankAccountManager类没有相同的响应性)。您可以根据性质对方法进行分组,您应该会看到其他类。
从那以后它应该是确定它们之间是否存在任何1对1,一对多和多对多关系的简单情况。在Java中,这些将由单个实例或列表和方向性表示(A类知道B类还是单行道?)由相应类中的引用的存在与否来表示。
P.S:请注意,我正在松散地描述的是一种方法论方法,而UML只是通过描述来自不同视图的系统来实现自我。