Object-Oriented Design: The Curse of Choice

I love OO because there are so many ways to accomplish the same thing. I hate OO because there are so many ways to accomplish the same thing. But I love to noodle through the issues.

I have a simple one that everyone has run into: let’s call it the Constructor vs. Property vs. Method Debate.

Suppose that, given a URL, I want to save a snapshot image of that URL to a named file. There are (I think) four OO ways to accomplish that. Let’s assume the worker class is called “Snapshotter”.

OPTION 1: CONSTRUCTOR ONLY

Snapshotter s = new Snapshotter("http://foo.com", "c:\foo.jpg");

OPTION 2: CONSTRUCTOR + METHOD

Snapshotter s = new Snapshotter("http://foo.com", "c:\foo.jpg");
s.TakeSnapshot();

OPTION 3: PROPERTIES + METHOD

Snapshotter s = new Snapshotter();
s.Url = "http://foo.com";
s.File = "c:\foo.jpg";
s.TakeSnapshot();

OPTION 4: METHOD

Snapshotter s = new Snapshotter();
s.TakeSnapshot("http://foo.com", "c:\foo.jpg");

So which is best? Or, to put it a better way, are there advantages or disadvantages to any of the methods? XP would probably opt for #1 under the principle Do the Simplest Thing that Could Possibly Work. But is that really the best long-term design? I have a hunch that overloading constructors as substitutes for methods can get unwieldy pretty fast, and require refactoring. Isn’t that what software engineers are paid for — to prescribe designs/architectures based on our experience? However, with unit testing and code coverage providing peace of mind, why not?

I also have a hunch that OO purists would gasp at #1 as not being “sufficiently OO”, because you’re not explicitly sending a message to the object to tell it to do something.

Option 4 seems the next simplest, but here the thought that runs through my head is: why do you need to instantiate an object at all? Why not just use a static class method:

// static method replacement for #4
Snapshotter.TakeSnapshot("http://foo.com", "c:\foo.jpg");

This seems easy in the XP sense, if not really OO (even to my way of thinking).

The next thing to consider is: what is this object’s state? Does it have any? In the previous example, you can see I coded away any notion of a stateful object.

Consider other things you might want to do with this Snapshotter:

  • Send the snapshot via e-mail
  • Save it to cache so you don’t have to retake the snapshot later
  • Compare the new snapshot against previously cached versions of the same URL
  • Provide the caller with options to get the snapshot as a binary stream, instead of saving to a target file

… all pretty reasonable options, depending on what you might be trying to accomplish. Now, the design becomes a bit more obvious:

Snapshotter s = new Snapshotter("http://foo.com");
s.SaveToFile("c:\foo.jpg");
s.SendTo("anthonys@xidey.com");
DiffInfo d = s.Diff();
Stream s = s.GetStream();

Now we see that the state of the object revolves around the URL, and that our original file-saving requirement is just one of many possible actions / methods that we could invoke on this stateful object.  Thus, our original debate comes down to a victory for the OPTION 2: CONSTRUCTOR + METHOD option, albeit with some changes to what we’re passing, based on the statefulness of our object.

Advertisements

0 Responses to “Object-Oriented Design: The Curse of Choice”



  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s





%d bloggers like this: