tags:

views:

168

answers:

7

I'm trying to design a program that uses a third party API. The third party API describes an input with 296 fields, and an output with 179 fields. Obviously I want classes to represent the input and output. Are there any tricks to designing a class with so many fields? Should I have a normal getter and setter for every field?

Note: Because you ask, the API takes a string with all the fields in fixed width format as input, and returns a string with the output also in the fixed width format. It's very hard to interpret a non-flat structure out of that.

+2  A: 

I'd seriously consider simply using two hashtables if ultimate performance isn't the killer criterion.

Nicolas78
`EnumMap` should be pretty fast (non-linear reading of enum ordinals will likely be the worst part, I'd guess; but that's probably better than different code for different fields).
Tom Hawtin - tackline
+2  A: 

Can you use a java.util.Map instead of a class with setters/getters ?

Pierre
And what, have 296 constants for field names? Also, since the fields are of different semantic types (text, numeric, etc) I'd have to have some abstraction as the value.
C. Ross
You may have to create constants anyway, if you need to do comparisons in the code against the field names for example.
Dana the Sane
@Dane A fair point, but I usually use reflection and sometimes attributes for that.
C. Ross
+1  A: 

Wow, that's a lot of fields. Regardless...

How does the API interact with this class? If it provides an implementation of the class structure required, you should definitely go with that.

Mike Caron
The API expects a bloody string with all those fields set up in fixed width format. No real help there.
C. Ross
Oh. I'm so sorry :( Good luck...
Mike Caron
+2  A: 

Perhaps wrap API methods having unwieldy number of parameters and apply Introduce Parameter Object refactoring repeatedly, grouping logically related parameters into parameter objects, especially if results map into existing model objects wherein adaptor pattern could be applied.

unhillbilly
+5  A: 

Yikes.

One options is to simply use a Map or similar property holder.

Another option: use a series of nested classes, to add organization (e.g. Order.Person.ContactInfo.Address.ZipCode, rather then just Order.ZipCode). I'm not at all sure I like this one, as it means additional complexity, but without it, finding the particular getter/setter you want (say via autocompletion in an IDE) becomes a nightmare.

Yet another option: if you do create a single class with many properties, consider using the "expression builder" pattern, in which each "setter" returns the object itself, enabling you to chain setters together:

myObject.setPropertyA("Foo").setPropertyB("Bar").setPropertyC("Baz")...

which can create a quicker and more fluent interface then

myObject.setPropertyA("Foo");
myObject.setPropertyB("Bar");
myObject.setPropertyC("Baz");
...
JacobM
+1 for builder pattern fluency. Forgot to toss that in my answer.
unhillbilly
A: 

The third party API must be declaring some type/class for handling the output data, right? Assuming this API is a Java class, then obviously they need to return a single Output object from their method.

If this is the case, to interact with this API I would create a wrapper object which

  1. Wrapped the input fields/object and output object
  2. Only had public accessor methods for the fields my program cared about interacting with (I have a feeling that you don't need to access all 296 fields)

This way, the rest of your program only needs to know about the existence of the fields that it needs to know about, and the rest of the fields (and the 3rd party objects themselves) are completely hidden/abstracted away.

matt b
See the edit to the question.
C. Ross
@C. Ross, does your application care about every single input and output from this third party API?
matt b
@matt 95% are used in one place or another, if only to record so the user can see them.
C. Ross
+2  A: 

How about code generation? Create a file with the input parameters and another with the output parameters. Then create whatever code templates you want: getters, setters, constants. Then multiply the two together.

If you need to re-architect it, just modify the templates and regenerate.

aepryus