Distinguishing Compositions and Associations


For all the application developers out there, this is a request for comments.  In business apps there are generally two types of relationships: compositions and associations.  Compositions are tightly-coupled relationships where the composition's lifetime is tied to its parent.  Associations are loosely-coupled reference relationships.  In designing a prescriptive framework such as the Microsoft Business Framework, it may be beneficial to the application developer to distinguish compositions and associations from each other while coding in a way that does not involve referring to the documentation.  In other words, how can I tell that when I navigate from Order to Customer (as in Order.Customer) that I am referring to an association rather than a composition? 

So two questions for everyone:

  1. How useful would it be to be able to distinguish between compositions and associations when coding against those relationships?
  2. What ideas do you have to help make that distinction?

Comments (4)
  1. Michel says:

    1. I really don’t know how useful it would be with the notational complexity that would come with it. Or in the case below with the implicit operators its only a declarative property. But as .NET programmers usually is quite bliss about lifetime and resources it might be good to force them to think about it in the design phase and have it expressed in code.

    2. The obvious solutions as I see it within the .NET environment would be to use some kind of naming convention I.e Order.CustomerRef or by using functions for references lik Order.GetCustomer()/Order.SetCustomer(cust) or Order.Customer()/Order.Customer(cust). This is as opposed to Order.ShippingAddress = new Address(); for containment/composition.

    Another solution wich i would prefer be to use some kind of generic Ref and/or Val class to denote a reference or containment.

    struct Ref <T>

    {

    private T _ref;

    public Ref(T reference) { _ref = reference; }

    public T Ref { get { return _ref; } }

    }

    declared like

    Ref<Customer> Customer;

    used like

    order.Customer = new CustomerRef(lookup.GetCustomer(4711));

    Customer c = order.Customer.Ref;

    struct Val <T>

    {

    private T _val;

    public Val(T val) { _val = value; }

    public T Val { get { return _val; } }

    }

    The value class could use real value semantics if T supports cloneable and make an actual clone of T when assigning it.

    Adding implicit operators this can be used

    public static implicit operator T(Ref<T> r) { return r.Ref; }

    public static implicit operator Ref<T>(T r) { return new Ref<T>(r); }

    It can be declared as Ref or Val but still used in code as usual.

    In C++ I have used shared_ptr/ptr types as opposed to references or value types to distinguis the two kinds of relationships in my models. But I don’t see how this cleanly can be transferred to .NET.

  2. 1. As you guys already mentioned, lifetime management could benefit, e.g. need to call Dispose on the dependents. Also, some code-generating or mapping tools could get a little smarter; say, for generating a database persistence layer.

    2. Relationships with 1:n cardinalities are good composition candidates. In WMI/CIM you have weak associations or in relational databases the foreign key attributes being part of the primary key. If your object can only be identified within the scope of another object, it’s likely to be part of a composition.

    In the Order.Customer situation, if you’d have a database, there would be a foreign key in Order identifying the Customer, not vice versa.

  3. Chris Garty says:

    Do you really need to differentiate between the concepts of composition and association?

    Can’t you just deal with individual behaviours in the meta-data (XML or attributes) of the reference?

    For example…

    When you talk about lifetime control I assume you are talking about cascading things like updates and deletes up and down the object graph. Can’t you just provide a cascade .net attribute/XML mapping atttribute that provides information about the cascading of updates and deletes?

    e.g.

    In class Cat…

    [CascadeDelete, CascadeUpdate]

    List<Kitten> Kittens;

    Or in the metadata file Cat.mbf.xml…

    …Property=Kittens CascadeDelete=true CascadeUpdate=true…

  4. Adam D. says:

    Interesting question. It seems to me the heart of what you were asking was: "how can the programmer know whether this is acomp/assoc. without having to look it up?

    My first thought was, if you don’t know the design well enough, should you be coding to it? 🙂

    Bottom line is (if I understand you correctly :), are the behaviours for these types of references different enough (at the caller level) to warrant a syntactic distinction? IMHO, no. I can envision poking/peeking at both comp. and assoc. sub-objects at any given time, although pretty rarely in the case of assoc. objects. OTOH, if this is for, as was hinted by Mr. Boehlert, code generation, then maybe…

    Just my .02

    AD :{)}

Comments are closed.

Skip to main content