【问题标题】:Monopoly game - LSP OO principle大富翁游戏——LSP OO原理
【发布时间】:2012-02-20 04:27:48
【问题描述】:

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

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

让我从我目前的设计开始:

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

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

但这似乎与 LSP 背道而驰,因为所有这些不同的 Land() 覆盖方法将做完全不同的事情,正如我设计的那样。

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

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

【问题讨论】:

    标签: oop liskov-substitution-principle


    【解决方案1】:

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

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

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

    【讨论】:

    • 好吧,我没有详细说明 Land() 的实际作用。我设计的不仅仅是这个。事实上,我的空间永远不会改变状态;相反,PropertySpace 拥有一个可以更改的 Property 对象。那么你会说在 LSP 下合同应该被定义为做对象需要做的事情的最低要求是准确的吗?比如,Land() 只能更改它允许更改的内容,而不是关于登陆任何空间的垄断规则(在这种情况下恰好相当广泛)?
    • 例如,在 [in] 著名的 Rectangle/Square 示例中,getArea() 的合约为所有子类返回 width * height...。这就是 Square 违反它的原因,因为当您 setWidth(50); setHeight(10); 时,您期望通过合同获得 500。所以 LSP 非常依赖合同......我在正确的轨道上吗?
    猜你喜欢
    • 2012-02-22
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2021-02-08
    • 2016-02-18
    相关资源
    最近更新 更多