tags:

views:

114

answers:

2
+3  Q: 

OO Design Issues

Hi there,

I'm learning OO principles and for practice I'm developing an application in Java.

The application is to parse the hand history text files issued by poker sites after every poker hand is played and to extract the same types of data from the file no matter which site the hand history is from.

The hand history files can be in very different formats depending on the poker site. Some sites have each hand in a very human-readable style eg:

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

and others have an XML style.

My question is: When parsing the above line from the text, should I have separate classes to parse each element? For instance should I have a StakesParser class with a parseStakes() method and then a CurrencyParser class with a parseCurrency() method etc. Or should I have a single class that can parse that line and get all the different bits of info from it?

To have a separate class for each thing I want to parse seems more OO, but less efficient. Any advice?

What I want as a result of the parsing process is a GameState class which would hold all the info for one hand of Poker. So no matter what site the hand history file was from I would be able to make an object of type GameState with all the relevant info parsed for it by an HHParser class.

To this end, I thought it would be a good idea to have an interface which would have to be implemented which would ensure that the HHParser for each poker site would end up producing a GameState class. So the interface would have methods such as parseStakes(), parseCurrency() etc. Is this the right approach?

What makes it more confusing for me is that on different sites, the information is in a different order so I possibly need a controller class that makes sure that each method is called in the right order depending on what site the text file is from.

Sorry about the waffle, but I'd be grateful for any pointers on what is might be best to do.

Many thanks in advance. :-)

+1  A: 

Since it is just a single line of data, I recommend having a single parser object that deals with parsing out the currency, stakes, etc. This class could then instantiate different objects to hold the data.

This does not violate OO principles since the parser class has a single responsibility of reading text data and generating Java objects from it. And each Java object has the responsibility of holding it's given data for use by your program.

Justin Ethier
Hi Justin. Thanks for your reply.For the sake of brevity, I didn't explain that each hand history for every poker hand is about 20 or so lines long. It has a line that will say that its the start of a new hand, then it will have a couple of lines telling you what the stakes are etc as in my original post. Then it will have some lines describing who the players are and their stack sizes, then it will describe the play.
Joe
The problem with having a single object that reads that one line is that the info on different sites is in a different order, or on a different line, or in XML format.I have vague ideas about implementing an interface and also having factories for instatiating the right type of parser etc. but at the moment it's blowing my mind a bit.
Joe
Well, OK, to separate concerns you would need one parser object for each data format. So there would have to be a text parser, XML parser, etc. Of course each would still have the same base class...
Justin Ethier
OK, so I could have, say, an abstract class for say AbstractXMLParser and AbstractNonXMLParser which have methods that can be used by Parser classes that subclass them but each class would then go on to have the extra methods that they would need for the specific site.Thanks v. much Justin.
Joe
+4  A: 

I wonder if a "class per element" strategy is too granular. I'm thinking maybe some sort of factory that returns the correct parser implementation for a particular site.

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

So you end up with a Parser interface responsible for returning some sort of java bean encapsulating the attributes of a poker hand.

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

And you implement Parser for each site from which you can obtain hands, returning the correct one from the factory. I might use Commons Digester for the XML sites and ANTLR or even regular expressions for the non-XML ones.

jcrossley3
OK thanks jcrossley3. I've been tying myself up in knots trying to "make it OO" when it seems like I won't be able to reuse much of the code and if I do it the way I was then I'll end up having thousands of classes confusing me more. I'll try to reuse code where I can, but other than that I can have one Parser class per site controlling reading and parsing of the text file and producing the GameState java bean object. Cheers.
Joe
Not to sound too preachy, but always remember that OO is a "means", not an "end". OO is a great tool, but like a chainsaw, it's capable of enormous destruction.The trickiest part of OO is figuring out the optimal granularity of your abstractions. Sure, it's possible to abstract every single noun in your domain model into a class, but doing that may only confuse the people who have to maintain your code.Actually, that's a good rule of thumb: only add an abstraction (class) when you think it'll help the dude coming behind you to grok your design. :)
jcrossley3
Also, IMHO reuse is not the best selling point of OO. Reuse is damn hard to get right, and OO alone won't get you there. The best selling point of OO is clarity, enabling you to better express your intent in a way that both computers and, more importantly, HUMANS can understand. Good luck!
jcrossley3
Cool. I appreciate your comments.
Joe