面向对象设计问题

3

我正在学习面向对象的原则,并且为了练习,我正在使用Java开发一个应用程序。

该应用程序旨在解析扑克站点每次玩牌后发布的手牌历史文本文件,并从文件中提取相同类型的数据,无论手牌历史是来自哪个站点。

手牌历史文件的格式可能因扑克站点而异。一些站点以非常易读的方式呈现每个手牌,例如:

NL $0.25/$0.50 Texas Hold'em - Tuesday, June 22, 19:55:24 GMT 2010

我的问题是:当从文本中解析上述行时,我是否应该有单独的类来解析每个元素?例如,我应该有一个StakesParser类和一个parseStakes()方法,然后再有一个CurrencyParser类和一个parseCurrency()方法等等。还是应该有一个单一的类,可以解析该行并从中获取所有不同的信息?
为了进行解析过程,我想要的结果是一个GameState类,它将保存一手扑克牌的所有信息。因此,无论手历史文件来自哪个网站,我都可以通过HHParser类解析出一个GameState类的相关信息。
为此,我认为最好有一个接口,必须实现该接口,以确保每个扑克网站的HHParser最终都会生成一个GameState类。因此,该接口将具有parseStakes()、parseCurrency()等方法。这种方法正确吗?
让我更困惑的是,在不同的网站上,信息的顺序是不同的,因此我可能需要一个控制器类,确保根据文本文件来自哪个网站,调用每个方法的顺序是正确的。
很抱歉啰嗦了这么多,但我会非常感谢任何关于最佳做法的指导。
2个回答

4

我想知道“每个元素一个类”的策略是否过于细致。我在考虑可能需要一种工厂来返回特定网站的正确解析器实现。

public class ParserFactory {
  public static Parser get(String url) {...};
}

因此,您最终会得到一个解析器接口,负责返回一些Java bean,封装了扑克牌手的属性。

public interface Parser {
  public Collection<Hand> parse();
}

您需要为每个网站实现解析器,以获取手牌,并从工厂返回正确的解析器。对于XML网站,我可能会使用Commons Digester,而对于非XML网站,我甚至可以使用ANTLR或正则表达式。


好的,谢谢jcrossley3。我一直在试图“使其面向对象”,但似乎我无法重用大部分代码,如果我按照之前的方式做,最终会有成千上万个类让我更加困惑。我会尽可能地重用代码,但除此之外,每个站点可以有一个解析器类来控制读取和解析文本文件,并生成GameState Java Bean对象。干杯。 - Joe
不想听起来太说教,但请记住,面向对象编程是一种“手段”,而不是“目的”。面向对象编程是一个伟大的工具,但就像链锯一样,它能够造成巨大的破坏。面向对象编程最棘手的部分是确定抽象的最佳粒度。当然,将域模型中的每个名词都抽象成一个类是可能的,但这样做可能只会让维护代码的人感到困惑。实际上,这是一个很好的经验法则:只有在你认为它有助于后来者理解你的设计时,才添加一个抽象(类)。 :) - jcrossley3
此外,在我看来,重用并不是面向对象编程的最大卖点。重用很难做到,并且仅靠面向对象编程是不够的。面向对象编程的最大卖点是清晰易懂,使你能够更好地表达自己的意图,让计算机和更重要的是人类都能理解。祝好运! - jcrossley3
很好,感谢您的评论。 - Joe

1

由于它只是一行数据,我建议使用一个单一的解析器对象来处理货币、赌注等的解析。这个类可以实例化不同的对象来保存数据。

这并不违反面向对象的原则,因为解析器类有一个单一的职责,即读取文本数据并从中生成Java对象。每个Java对象都有保存其给定数据以供程序使用的责任。


嗨,贾斯汀。感谢您的回复。 为了简洁起见,我没有解释每个扑克牌局的每个手牌大约有20行左右。它有一行会说这是新一手的开始,然后会有几行告诉你赌注等等,就像我原来的帖子中所述。然后它会有一些描述玩家和他们的筹码量的行,然后它会描述游戏的进行。 - Joe
拥有一个单一对象来读取那一行的问题在于不同网站上的信息顺序不同,或者在不同的行上,或者以XML格式呈现。我对实现接口并为实例化正确类型的解析器等设置工厂有模糊的想法,但目前它让我有些困扰。 - Joe
好的,为了分离关注点,你需要为每种数据格式都创建一个解析器对象。因此必须有文本解析器、XML解析器等等。当然,每个解析器仍将具有相同的基类... - Justin Ethier
好的,那么我可以创建一个抽象类,比如AbstractXMLParser和AbstractNonXMLParser,它们拥有可以被子类化的Parser类使用的方法,但每个类都会继续拥有它们需要的特定站点的额外方法。非常感谢,Justin。 - Joe

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