tags:

views:

77

answers:

4

Let's say one has a class that performs a certain type of task. And let's say that there are a number of variations of that task. The actions are the same, just a few parameters change (e.g., for soft boiled egg, action = boil, time = 5 min.; for hard boiled egg, action = boil, time = 11 min., etc.). Number of parameters that vary is about 10.

I see there are three ways to do this:

  • Use a switch and set the params in code based on type.

  • Save the parameters in a database or file and retrieve them based on task type.

  • Subclass the task, overriding the parameters of the parent class and instantiate subclassed objects to perform the task in question.

The first option is clumsy. But how do I decide between the other two?

1) Retrieve parameters from file or db.

  • PRO: No need for subclassing or factory. Simple.
  • CON: Requires additional query or file access. Parameters no longer visible in code.

2) Subclass the task.

  • PRO: Does not require additional query or file access. Parameters maintained in code.
  • CON: Proliferation of classes and need to make factory.

Have I correctly identified the pros and cons? What other criteria should I use to decide the issue?

Please advise. THANKS!

A: 

I think your CON may be understated for the DB-parameters option. If the number of parameters that can vary is about 10, you're still likely going to be dealing with if/switch logic inside the routine that pulls those parameters.

Given your description, the overhead of writing sub-classes and a factory method sounds like a lesser evil than your logic involved in variable parameters.

jro
@jro -- Thanks. Should I assume from your answer that both are evil (though one is the lesser) and that there may be another option? Or am I reading too much into your answer?
Clayton
Nah, no intention implied. Just semantic usage of the phrase.
jro
To add to the description, your classes should only proliferate if the logic requires it. All things considered, the class overhead becomes less minimal the more complex your logic becomes. 10 variable combinations is certainly enough for me!
jro
You may be right. THANKS.
Clayton
A: 

My instinct says that if the objects are of logically different classes they need to be of physically different classes.

Option 1 might be acceptable for specific problems, but options 2 is way out. A class should be self-defined without deference to runtime data. (there's probably even exceptions to that too, but I like hyperbole)

annakata
@annakata - Thanks. But forgive me, I'm having a little trouble understanding your answer. Are you suggesting that subclassing is the better option? It seems that way, but I'm not quite certain. Sorry. Thanks for any clarification you can provide.
Clayton
Yes, I'm saying subclassing - and probably that means making the parent abstract.
annakata
@annakata - Thanks for clarifying!
Clayton
A: 

I had the chance to work with 2 similar systems on 2 different projects. The first went through the sub-class route, and the second through the configuration route (db in our case).

The first made the team feel they had a lot of power to customize it, as its subclasses could also have very specific behaviors. With time, understanding the system wasn't that direct, as these bits of behavior is hidden in the subclasses.

On the second system, the configuration read pretty clear what was expected from each specific case, both on data + behaviors. Testing the classes became focused on testing they handled these settings well. With time some base configurations where added, which enable overriding specific features when needed. To reduce amount of code being handled by the main class, some behaviors were moved to specific classes, and they where loaded based on the configuration.

I found the second approach pretty powerful when on a highly dynamic environment, where new data/understanding of how it was going to work kept coming in. Settings/behaviors where clearly defined/handled by the classes, no open keys with data that the system didn't understand.

That said, this doesn't mean that this configuration needs to be maintained externally. You could easily have code that adds the different configurations to a list of active configurations. If you use that with the builder pattern, giving defaults to it, you can have a similar base configurations approach with not that much code.

eglasius
+1  A: 

If it's only the parameters changing and the algorithms stay the same, then I would create one immutable class that contains the algorithm and create multiple instances of that class, each instance with different parameters. Store the configuration instances in constants or some data structure. Like this in pseudo-code:

constant SOFT_BOILED_EGG = new EggBoilingStrategy(BOIL, 5 min)
constant HARD_BOILED_EGG = new EggBoilingStrategy(BOIL, 11 min)

This will also make it possible to create subclasses that contain a different algorithm.

Much will depend on the way that you need to access the configurations. You could store them in a map, which would make adding new configurations easy. Or then you could hardcode the references to them.

Esko Luontola
@esko-luontola Interesting! Thanks. I'll need to mull this over.
Clayton