关于Ruby面向对象设计的问题

6
我计划用Ruby编写一个CLI版的大富翁游戏,这将是我在Ruby中做的第一个大型项目。我大部分的编程经验都是使用函数式编程语言,如Clojure和Haskell等。我对面向对象编程有很好的理解,但我没有设计面向对象程序的经验。
现在,问题来了。
在大富翁游戏中,棋盘上有许多空间。大多数空间是属性,其他空间则有其他功能。
为每个空间创建一个类会不会很明智呢?我想创建一个Space类,所有其他空间都从它继承,然后创建一个Property类,它从Space继承,然后为每个属性创建一个类,它们从Property继承。这意味着会有很多类,这让我觉得这种方式不适合我要做的事情。
我的另一个打算是使用'inherited'钩子方法来跟踪所有属性,以便在需要时搜索它们并从未购买列表中删除它们。
这种问题似乎在许多程序中出现,所以我的问题是:是否有更好的方法来解决这个问题,我是否缺少面向对象设计方面非常关键的知识?
如果我的问题很愚蠢,请原谅,我对面向对象程序设计一窍不通。
谢谢。
2个回答

9
你走在正确的道路上,但你已经走得太远了,这是面向对象编程中常见的初学者错误。每个属性不应该是一个单独的类;它们都应该是 Property 类的实例。我会按照以下方式使用带有属性的类:

空间

  • 名称
  • 上面有哪些棋子
  • 下一个空间是哪个(也许还有前一个?)
  • 着陆时发生的任何特殊动作

属性(扩展自空间)

  • 所有者
  • 有多少房屋/酒店
  • 财产价值
  • 财产垄断组
  • 租金率
  • 是否抵押
例如,Boardwalk 将是 Property 类的一个对象,具有适用于它的特定值,例如属于深蓝色垄断组。

哦,我明白了。这听起来确实更好。我还在努力想象如何跟踪所有属性。但是,实例化那么多次Property不会被认为是样板代码吗?我相信有一种更好的方法可以为每个属性实例化Property,而不必为每个单独的属性显式地实例化它。只是我现在没想到。 :p - Rayne
2
类是样板文件。它们旨在封装重复的属性和行为。至于每个属性都要显式实例化,无论如何都必须实例化属性。但您不必明确执行此操作。例如,您可以将有关属性的数据封装在 XML 文件中,并在启动时让程序实例化每个属性。 - Pesto
我明白了。只需一个接一个地实例化它们,就可以按照我想要的方式完成操作。我不确定连续这么多次实例化是否会被认为是一件坏事。非常感谢您的回复。您帮了我很多忙。 :) - Rayne

4

为方便理解,创建空间类可能是个不错的想法,现在我们来看看原因。

如果你使用过程化语言编写此项目,那么大部分的if和switch语句将用于确定每个玩家落在哪个位置时应该发生什么。在面向对象编程中,我们希望尽可能避免if/switch语句,并用多态性替换它们。因此,显然,如果我们创建许多Space的派生类,就可以避免大量的if/switch语句。

但在我们迈出这一步之前,让我们看看游戏的隐喻。这个游戏全部围绕着一个城市展开。有地址、街道、公共设施、监狱等等。棋盘上的每一个方格都代表城市中的某种位置。确实,玩家在旅行中无论落在哪里都要支付租金(或进行其他操作)。

所以我们把空间称作CityBlocks。每个CityBlock都有一个地址,比如“Boardwalk”、“Electric Company”或“Community Chest”。CityBlock对象有不同的类型吗?还是我们只需将CityBlocks视为具有特定ZoningOrdinance的位置?

我比较喜欢后者。|CityBlock|---->|ZoningOrdinance|

现在我们可以有几个不同的ZoningOrdinance派生类。这就是“策略”模式。我喜欢它提供的灵活性和“何时(where)”与“什么(what)”之间的分离。

你还需要一个Game类来理解骰子、代币、FreeParking、过Go等规则。该类将操作玩家,并调用CityBlock上的方法。CityBlock将调用ZoningOrdinance上的方法。

总之,这是一种方法...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接