Having the Same Object Handle Multiple Tasks

It’s often tempting to write some code to do a task and make it generic enough to handle similar but different tasks.  A great example that we dealt this this week was a picker dialog that was used generically for people, organizations, and skill sets in a Xojo web app.

It made sense.  The dialog is called from multiple places and it does the exact same thing in each place (displays a list and the user can filter on the list).  What’s different is what data we pass into it for initialization and what data it loads for display.  We wanted the exact same UI in all three cases.

We all want to write as little code as possible.  That’s what’s great about being a lazy programmer.  Do more with less.  That works until it doesn’t and, to be honest, we’ve learned, the hard way, that sometimes the best approach is to make your objects do one thing and one thing only.  Why?  Because inevitably the client will say, this is great, but we want to filter for ‘x’ on people, and ‘y’ on organizations, and neither of those things are interchangeable UI-wise and neither x nor y make zero sense for skill sets.

The first approach is to put lots of if-then-else blocks into what was once a very generic picker dialog.  Now it’s a complex UI that has three distinct code paths.  This complicates testing since every time you make a change it now has to be tested in all three areas.  What worse is the code becomes complex and if you’re in a hurry (and who isn’t?) it’s easy to change the WRONG bit of code.

Our solution was to write the first dialog, get the UI working properly, and then duplicate the entire object and customize it for its new task.  <Gasp>  I know, bad OO programming, right?  We disagree and that’s coming from the school of hard knocks.

The end result is that we have specific pickers for people, organizations, and skill sets.  It’s now simple for a developer to make a change for the picker in question.  No longer do they have to think, “gee, which datatype am I fixing this time,” and possibly get it wrong.  Keeping it simple reduces accidental coding bugs and it reduces unintended bugs due to code changes.

Testing also becomes easier because if we’ve done something to the employee picker, we don’t have to test organizations or skill sets.  Likewise for the other two areas.  Simple is good.

The one area that it does become a bit messier is if we have to do general user interface overhaul.  Now you potentially have three places to do it.  However, since we have WebStyles with web apps this becomes trivial unless you’re rearranging UI elements.  Xojo Desktop apps are a little harder since there are no styles but in those cases it’s actually fairly easy to copy/paste UI from one form to another (assuming that’s possible).

Call me cynical, but I would gladly work on UI for an hour to ensure they’re identical to futzing around with code in three separate code branches that are nearly identical.  I am a lazy developer after all.

Our experience says that generic, reusable objects, often lead us into trouble, so we tend simply not to do them.  But how do you teach that to a new developer and one that’s trying to do their best to use good OO conventions?  And when do you reach that breaking point where the generic way makes it harder than its worth?  Good questions that I don’t have good answers for.

Happy coding!

5 thoughts on “Having the Same Object Handle Multiple Tasks

  1. Of course another option rather than cutting & pasting is to make a superclass which contains all the controls, then subclass for each of the different types. A little more work, but it separates out the display logic & the data logic. That way if you change the layout you only need change that in one place, while you still have a separate object for each datatype.

    This is a much easier option for those layouts which use dynamic nested container controls, as each parent can be set up to use the super for positioning rather than bothering which datatype container control it is.

    • This assumes, of course, that the return never changes. Just this morning I had to change two pickers to return multiple items. The project I’m referring to didn’t just have 3 pickers it had 7. So 2 of my 7 changed this morning. I suppose if I had done it the super-class way it wouldn’t have been a big change code-wise but then when it comes to testing I’d still have to test all 7.

      With my copy-paste way we only have test 3 instead of 7. Since time is money (and all that jazz) this non-oo approached saved me some testing time.

      • Sure, there are times when the superclass option is the best, and times when it is not; all just tools for the job.

  2. Bob,

    I tend to go back and forth on that one. But I tend to end up with individual controls just for the same reasons you pointed out.

    sb

    • The analytical part of me says having 3 separate objects to do the same thing is bad. The practical side of me has proven over the years that it’s faster/safer to do so.

Comments are closed.