I had this feeling for a long, long, long time. I always found that object modeling in UML helped giving birth to what Eric Evans calls the "ubiquitous" domain language (in his book "Domain-Driven design"). As a consequence, I thought that object programming languages were really missing an "association" type of attribute that would convey the kind of meaning you have in your class diagram.
This was just the kind of idea that could be somehow implemented someday in java10 after extensive academic research (that was certainly going on the subject - isn't it the classical way of promoting new programming languages?).
Anyway, all this was just day-dreaming and practically speaking I was more or less mentally mapping the object business model to my java classes. Alternatively, I used Together's java annotations to describe the collections.
But we are now facing a though challenge that many people must have dealt with in many places (the question is: who and where - please email me,...) : how can you evolve an existing graph of objects from an XML file that is supposed to represent its next state. This is not so easy because:
- if an object is not present in the XML anymore, it has to be removed from the object graph everywhereit is used, and due exceptions must be sent if it shouldn't be allowed. Failing to do that properly would cause nasty errors in our object database
- changing the state of objects can have various impacts on other objects in the graph and those impacts can trigger a "chain-reaction" from the bottom of the object graph to the top
Then I would use this metamodel for several things:
- generically produce the XML equivalent of the business objects
- computing differences between the "state before" and the "state after"
- sending the differences to our internal "EventBus"
- generically having the business objects subscribing for the changes that are applicable to them
- let the business objects do their job and send other events for the possible impacts
- when you create your classes, they have relationships through pointers even if all the semantic of the association is not declared
- when you create your metamodel, you add more information to the existing one
So I decided to create Association classes that would satisfy all our requirements for minimum redundancy, maximum robustness and distributed behavior among classes:
- ZeroManyAssociationList/Map (implementing List/Map)
- ZeroManyCompositionList/Map
- OneAssociation
- ZeroOneAssociation
- ...
- when a business object is removed, all the containers are notified and can cleanly remove their reference to that object
- a OneManyAssociation can check that the lower multiplicity is respected
- a Composition association can now be used generically to know what to do in case of the removal of the owning object
- an association can be constructed with its owner and warn him that its content has changed
- ...
- The type of a ZeroOne or a One Association is not the type of the referred object. It could be interesting to use a dynamic proxy here, however I don't think that it would work with JDO (the database API we use)
- Business objects diagrams with Together will be unnecessarily cluttered by those container classes.
Yet, as for any design where you have to decide between conflicting constraints, I think that if this solves elegantly our need for a more robust object model, this is really worth the price.