我正在尝试设计 Bejeweled游戏。我基本上有3个类(class)。 Game
类,玩家将要使用的类,Board
代表董事会的类(class),以及一个SwitchController
该类负责检查棋盘上所需的开关是否有效、进行开关、计算可用开关的数量(这样我就可以知道游戏何时结束等)。
我目前的设计是这样的:
Game:
isGameOver()
isSwitchValid(coord1, coord2)
makeSwitch(coord1, coord2)
getPieceAt(coord)
getBoardLength()
IBoard:
getPieceAt(coord)
setPieceAt(coord, piece)
getLength()
然后我的想法是有一个 ISwitchController
:
ISwitchController:
isSwitchValid(coord1, coord2)
makeSwitch(coord1, coord2)
getAllValidSwitches()
下面是如何组织类的小图:
我会有 2 个不同的具体类 IBoard
可供使用(对于它们中的每一个,我都必须有一个 ISwitchController
实现)。
问题:
我的程序是有 2 个 IBoard 实现:
第一个,ArrayBoard
, 会将棋盘的所有部分存储在二维数组中。没有什么特别的。我将定义一个 ArrayBoardSwitchController
用于管理此类。
第二个,ListBoard
, 对于每种颜色的棋子,都有一个列表/集合,其中包含该颜色棋子的所有坐标。我将定义一个 ListBoardSwitchController
用于管理此类。
这里的主要问题是 SwitchController
的实现ArrayBoard
将完全不同和 ListBoard
.例如,在执行 getAllValidSwitches()
时ArrayBoardSwitchController
只需要 getPieceAt()
方法,这不是一个好主意ListBoardSwitchController
(在该类(class)中,我在内部使用列表,因为这样更容易检查移动是否有效)。
据我所知,有 2 种不同的可能解决方案:
我可以将
ISwitchController
和IBoard
接口(interface)。那样我就只有 两个类,游戏和棋盘(同时 基本上游戏只是一个 董事会的 Controller ,因为它 将是董事会拥有所有 游戏逻辑)。它不会那么好 因为类(class)不会 如果我有 3 个不同的类别。让界面保持原样并放置 我需要与公众合作的所有方法 在具体的类(class)中。例如,如果我需要 一个
getYellowPiecesList()
方法,我会把它公开 在ListBoard
所以ListBoardSwitchController
可以 用它。ListBoardSwitchController
只会 知道它是因为它知道它只管用 反对ListBoards
.
您对此事有何看法? 这里的重点不是如何设计 gem 迷阵游戏,而是如何解决这个问题,这个问题在您尝试实现算法时经常出现:一方面,您希望有一个清晰且良好的 OOP 设计,并且另一方面,有时这会妨碍实现可靠且有效的算法。
最佳答案
The main issue here is that the implementation of SwitchController will be totally different on ArrayBoard and on ListBoard.
如果是这种情况,那么听起来您还没有将 IBoard
接口(interface)设计得足够好,以至于类可以在不知道实现的情况下使用 IBoard
的实现细节。如果 IBoard
的用户需要知道正在使用什么实现,那么它几乎违背了拥有接口(interface)的目的!
我强烈建议重新访问您在 IBoard
上公开的方法,看看是否有一种方法可以以更通用的方式公开诸如“在此坐标处获取作品”之类的内容。确保 Controller 需要在 IBoard
实例上调用的任何方法仅 IBoard
接口(interface)中的方法。
For example, while for implementing getAllValidSwitches() ArrayBoardSwitchController only needs the getPieceAt() method, that would not be a good idea to do with ListBoardSwitchController(in that class I use internally lists because it's easier to check if the move is valid that way).
如果诸如“在此坐标处获取棋子”之类的操作对IBoard
接口(interface)有帮助,则实现必须忠实于它们的约定并正确实现它。听起来好像您的 ListBoard
没有忠实地满足 IBoard
中规定的契约(Contract)。
关于c# - 设计 gem 迷阵游戏的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3247065/