Time for a follow-up. I was pretty satisfied with my idea of implementing associations as first-class objects in our object-model. It truly serves its purpose : a fine management of relationships between objects: deletion, updating, adding,...
However, I would like to summarize also all the difficulties we had along the way, that's not always paved with flowers:
We have some objects that are build only for the purpose of the application session. Those objects are displayed to the user but not meant to be persisted. Yeah, right. But hey, anytime you are associated with a business object, an underlying Observer-Observable relationship is build. It's fine until the business object is persisted and JDO kindly does "persistence by reachability" to persist anything connected. Bang! A transient object is persisted,...
Modification impacts outside the aggregate
With our framework, each time the marketing adds a new ProductRelease to the Product, the Catalog can be notified. All this stays in the same hierarchy of objects. But what if a corresponding new ManufacturedItem should be created in the Factory ?
Loosing my memory
Objects are cool, objects are fine and RAM is cheap,... but not infinite! Adding new objects to manage the relationships also adds more data and we had surprises with our memory consumption.
Every relationship is managed as an association, even for redundant associations, that are only there for design reasons. As we also use our framework, in a very generic way, to create configuration files, we had never-ending instability each time a new association was added even if the business did not evolve.
A variant of the previous one. How should a cache of objects be managed? As a composition between the object owning the cache and the cached objects? Can the cached objects appear in compositions even if they are indeed shared?
Tackling the issues one by one
Ah the details,... They can truly turn any "brilliant idea" into "useless crap". Our current answers to those issues are:
- Transient/persistent: no obvious solution. Delete the objects when not used. Persist them temporarily if necessary. We are waiting for our supplier to implement JDO2.0 to implement an elegant solution.
- Modifications outside the aggregate: use the ubiquitous EventBus
- Loosing my memory: some attributes were unecessary on the associations. This had a nice impact. However since we don't have any way in Java to know who's using a specific object, we need to add extra-pointers
- Redundant associations / caches: this is a real case of "don't mess the business model with the design model". We redesigned our associations with more meaningful data. Is it a design association? Is the component object cached? And so on.
One more word: I wish we did all that in Ruby! Take a look at the ActiveRecords framework:
class Firm < ActiveRecord::Baseor
class Account < ActiveRecord::BaseIt seems so clean :-O
composed_of :balance, :class_name => "Money",
:mapping => %w(balance amount)
:mapping => [%w(address_street street), %w(address_city city)]