Marc Hughes

I am a developer from a bit west of Boston.

My recurring anti-pattern

22 Mar 2009

I don't know why, but I keep falling into a development pattern that I've long since decided that I don't like.  Imagine this... you have some object.  That object has a set of properties, that might change over time.  So instead of making a bunch of variables on the object, I make an array of some property object.  Something like this...

public class Attribute
  public var name:String;
  public var value:Object;

public class MyClass { public var attributes:ArrayCollection; // Array of Attribute objects. ... some more stuff }

It's a design flaw I made while working on TimelinerXE that I've come to regret due to the added complexity it adds, with the minimal benefit it gives.  It might feel like you're getting a lot of future proofing.  Someday, in some future version, when we add a feature to Timeliner so the flags can have a glow-color, it's just a new attribute in the list.  No new properties.  No new XML encoding/decoding.  It's beautiful.  But in reality it doesn't give you a whole lot since when new attributes are added in the future, you inevitably need to change code in several places anyways.  You still have to write the code to render the new property.  That "no new code" for xml encoding/decoding isn't true since you now have to worry about backwards compatibility and setting a default value if none is set in your file.

But it sure adds a lot of complexity.  Instead of your view binding to a property, it has to listen for collection change events, AND bind to values within the array.  Instead of just watching for the "title" property to change, you have to be ready for:

  • A brand new attribute named title to get added.
  • That attribute to change value
  • The title attribute to be removed
And you have to be careful not to have multiple attribute objects of the same type in there.  It's just not worth it.

Lately, I was working on a proof of concept for a content editor for a new product, and I fell into the same trap.  It worked well for the proof-of-concept, but that was only because it was a very simplistic thing.  No undo/redo, no saving, no stateful navigation.  Just a quick & dirty thing to show how something might work if we spent some development dollars on it.

I started taking that proof-of-concept to an actual working application, and ended up taking along that design.  Luckily, I decided to give Moccasin a try for a framework to build the thing in.  Mocassin doesn't support this sort of data model, so I began hacking it in.  I spent a few frustrating hours putting it in before realizing that I was solving the wrong problem.  Instead of making the framework compatible with my screwed up data model, I should just make my data model compatible with the framework.  In all of 15 minutes I changed my model to a much simpler "normal" property based data model, and bamn.  It all works far more easily, and I'm a lot happier with it.  Going forward it'll be a lot eaiser to finish this project.

So Joe, thanks for not having support for something like this in Mocassing, and making me think about doing it the simple, right, way.