[Normally I post on StackOverflow but as this is more a design/theory question rather than a code question I'll give it a shot here]
Most of my applications currently use a core object model that I originally wrote 6 years ago and which has just grown as needed - as with most of my stuff, it was coded as is, without thinking up a design first. Part of it is too inflexible, part is poorly designed and yet more is clunky. So I decided to start again from scratch rather than trying to retrofit a new API on top of the existing one. And I also decided to actually map out the full API first upfront, then write the code for it.
So far that approach is paying off I suppose and I have a nice little model brewing. However, I have one quandary in the new design. If you consider the automation models offered by things like Microsoft Word, most primary objects have a property named Application
which points back to a core object. My existing object model follows pretty much the same principle and I am using that in the new one too.
The current API however has a mix of approaches. Some objects store a reference to that root object. Others don't, and the property simply looks at a singleton "service" object, which at it's heart has a ServiceContainer
to look up registered objects. Yes, a service locator. Some get it passed in through a constructor, others look it up then store a reference. I normally like consistency, but this is a mess.
My new design isn't changing this approach - objects still will have a property back the the root object with the idea being all the objects behave the same and I don't have to (manually) go hunting for an application when writing code for a given implementation.
With that background information out of the way, here's my question. Should each object hold a reference to the root object, or should it not store a direct reference, but look it up somehow, ie from a singleton or a service locator.
With the former approach, I'm going to use more memory - 4 bytes extra per object per object as I currently compiled everything as 32bit. While that doesn't sound a lot and I'm sure I'm not going to be creating many thousands of objects I sort of want the base API to be as efficient as possible as no doubt the apps I stick on top of it won't be! This approach also means I'm going to have to pass that object reference around in every single constructor, not much of a problem for real code but makes writing tests a bit more complicated.
The latter approach means I save memory, but then I continue to use the bad practice of a service locator, and I supposed there's a at least the hint of a performance issue as having to lookup a reference isn't quite going to be as quick as returning a direct one.
Or, is there another approach that large object models use that I haven't considered above? As mentioned I normally just dive in, make something that works then leave it alone until it breaks or I need it to do something else.
I'm guessing the answer is going to be "just store the reference and stop complaining" but better to get a feel for other peoples opinions!