1

我正在设计一个大富翁游戏,同时也在阅读更多关于 OO 原则的内容。我正在阅读 LSP(Liskov 替换原则),发现要么我没有完全理解它,要么违反了它,应该改变我的设计。

(请注意:这个项目是个人的,只是为了好玩,所以我实际上并不关心代码的可维护性,但我只是要求个人教育和对 LSP 的理解)

让我从我迄今为止的设计开始:

BoardSpace是一个抽象基类,板上的每个“种类”空间都有一个子类。所以我有PropertySpace, TaxSpace, GoSpace, 等等。

BoardSpace有关于空间在板上的信息,还有一个抽象的void Land()方法,这样每个不同的空间在登陆时可以做不同的事情,因为它应该。这样,当我调用Land()当前BoardSpace对象时,它不需要关心或考虑其他任何事情,只做空间应该做的事情。对我来说,这是有道理的,听起来像是一个可行的解决方案。

但它似乎与 LSP 背道而驰,因为所有这些不同的Land()重写方法都会做完全不同的事情,就像我设计的那样。

还是我误解了 LSP?它与Land()“预期”或“描述”的工作方式有更多关系吗?在这种情况下,每个空间完全不同,所以没关系?或者它肯定是一种违规行为,我应该重新设计它?

附带问题:这会被认为是对继承的“滥用”还是对继承的良好利用?

4

1 回答 1

1

在 LSP 下,子类方法可以做与超类完全不同的事情,只要它们不违反超类的约定。所以实际上这一切都取决于你签订的合同有多广泛。

如果BoardSpace.Land()只允许改变玩家的状态,那么如果登陆一个子类允许玩家购买它(改变空间的状态),你就会遇到问题。但是,如果Land()允许更改着陆玩家和拥有玩家的状态、空间状态和卡组状态,则不违反 LSP。

尽管如此,将事情分解成更小的方法可能是一种很好的做法,您可以更准确地进行推理。例如,当您着陆时,该空间可能会对其执行特殊操作(例如抽牌),然后是玩家与该空间的所有者(其他玩家或银行)之间的交易,限制为该操作可以只会影响玩家的现金和卡组和卡组,交易只会影响双方的金钱和空间的所有权。

于 2012-01-27T04:45:57.093 回答