I'm reading the book on Domain Driven Design of Eric Evans - Chapter 5, concerning associations. One of his advices to reduce complexity of a model is to impose a traversal direction for the associations.
I quote:
It is important to constrain relationships as much as possible. A
bidirectional association means that both objects can be understood
only together. When application requirements do not call for traversal
in both directions, adding a traversal direction reduces
interdependence and simplifies the design. Understanding the domain
may reveal a natural directional bias.
How to chose a traversal direction for an association? Generally, when there is an association between two elements, it may be read and understood in the two directions. What may cause us to chose one direction over the other?
Thanks
When there's an association between entity A and entity B, you'll often find yourself using only A.B and never B.A. This may be because A is an aggregate root and is always your starting point, because you already have a reference to its A wherever you manipulate a B, etc.
I guess Evans simply suggests that you should add a traversal direction only when you need it and will use it in the code just after, as opposed to prematurely adding a traversal direction "in case we need it later".
Conceptually all associations are bidirectional. Nevertheless, when implementing them most end up being unidirectional since then you just need to maintain the links in one of the participants.
During design you may want to indicate the navegability to break the bidirectionality at the implementation level and facilitate the coding of the system
Related
I have short question about class diagrams. In my book we have class Person and class Gender and agregation arrow between them(with diamond pointing to person). Now, in general when I want to decide whether we have agregation or not I am using one of these two rules:
1.When you destroy class that is whole, than part can exist without it;
2.Class that is part in agregation relation, can be mutual to one or more wholes.
Now if we look at this example and rule number 2, it is OK, because one gender is mutual to one or more persons. But for the first one, if there is not person, than we can't talk about gender right?So I would set composition here. Probably I am missing main difference between these two. Any help is appriciated.
In general
Your rule about when using aggregation is not wrong. But it's unnecessarily complex. There is a simpler much simpler rule about when you'd better use aggregation: never.
This may sound provocative, but the hard truth is that the meaning of aggregation is not defined in the UML specifications, which makes it ambiguous and subject to a lot of unnecessary time-consuming debates:
Sometimes a Property is used to model circumstances in which one instance is used to group together a set of instances; this is called aggregation. (...) Precise semantics of shared aggregation varies by application area and modeler.- UML specifications 2.5.1, page 112.
I know, it comes as a shock. For years in my career, I have myself selected very carefully aggregation whenever there was a part-whole relation with non-exclusive ownership. But when I came accross James Rumbaugh famous quote, I challenged my own assumptions and realized how vain and subjective this quest was:
Keep in mind that aggregation is association. Aggregation conveys the thought that the aggregate is inherently the sum of its parts. In fact, the only real semantics that it adds to association is the constraint that chains of aggregate links may not form cycle (...) In spite of the few semantics attached to aggregation, everybody thinks it is necessary (for different reasons). Think of it as a modeling placebo.- James Rumbaugh in Unified Modeling Language Reference Manual, chapter 14.
So, whenever you have aggregation in a model, you could simply replace it with an association without real loss of information.
In your specific example
The association: Person ----- Gender expresses perfectly that a person has a gender, and that several persons can share the same gender.
If you want to be super-accurate, you could use the dot notation (with a small dot on Gender side). This would convey the information that Person owns the end of the association.
Composition would definitely be wrong here, because it's an exclusive ownership and no two persons could share the same gender.
Aggregation is ambigous: what is the whole, what is the part? If gender is a part, wouldn't character be a part as well. And what with the name, then ?
A final remark: if you want to implement this with Person having a gender:Gender property (an OOP mechanism called "object composition") the, you don't need aggregation (even if it's a popular practice).
Please Look at the following example:
1) The chairs are made of wood .
2) Paper is made from trees .
3) Biogas is produced by the fermentation of waste.
4) Asphalt is produced through the refining of petroleum.
Should these be Composition or Dependency?
In general
You can exclude UML composition: composition implies an exclusive ownership. But chairs are not the only products made of wood.
Dependency is either too much (once the biogas is made, there is no dependency to waste anymore) or not enough (the wood of the chair is part of the chair; it's a stronger relationship than a need-to-know-about).
Moreover it is not clear if you want the Chair to be a class on its own or an instance of a class product.
Specific cases
"Made of" expresses a relationship with parts that make a product. A typical pattern here is the bill of material. The relation is a simple association. Some people tend to use UML aggregation, but UML specifications do not define precisely the semantics, so leave it out to avoid ambiguity.
Here a (very simplified) diagram:
"Made from" expresses a transformation process, where some of the original products disappear in the process and others are created. Paper is made from cellulose which is extracted from trees. But the original tree is not in the sheet of paper.
Typically in process industries, like chemicals, this is represented by a "recipe", which is a sequence of inputs (waste) and operation to obtain products (biogas) and co-products (fermented residual waste). In other industries, this is represented by a "routing" that is a sequence of operations performed on a BOM (in this case, the BOM would not only contain components as previously shown, but also raw products that are transformed by the operations in the routing).
I will not show a diagram because this is quickly very complex, but again, it'll use simple associations.
In the end, "made of" and "made from" would both be represented in UML with associations. But only the semantic that you attach to it will change.
I don't think that any "made of" is represented by some static relation. To make a wooden chair it just Depends on wood. There is no other relation here because you have some complicated process to turn wood into a chair. Or a tree into paper. Or anything else of your choices. In order to describe the relation you would need to describe the process. This is possible using activities. You could as well descibe physical components with UML. But that would take us too far apart from your question...
You might search for answers on composition here. But even these can be looked at controversial. Modeling reality yields a model. Which is not reality.
Your question highlights the difference between an ontology and an information model or application design. For example, in a conceptual ontology (which accounts for necessary and possible situations in the world rather than for data formats of observations and measurements), every person has a mother. In a particular database or application, that knowledge is usually irrelevant. What stuff is made of and how it is produced belongs more to a conceptual ontology, for which UML is not quite expressive enough. This is why languages such as First Order Logic (FOL) and OWL are used instead, and why some tools (such as my company’s) plug holes in UML. (One example of a hole in UML is the inability to express exactly the intersection of two classes.)
I understand the differences between the three( or at least I think I do). I know there are many other similar questions with definitions like this one.
I was looking an example from gliffy.com and I am strugiling to understand why some releationship were used they way they were used. I guess what I'm really struggling with is understanding when to use association.
Some of the questions I have are:
Why is Customer-Order and Customer-Credit Card an association an not aggregation like Customer-Address?
Why is Order-ItemOrder not composition given that ItemOrder would not exist without an Order?
Why is ItemOrder-Item not aggregation?
In order to answer these questions, it is important to know why this class diagram is drawn. Only the author knows, but maybe it is just a demonstration of the capabilities of gliffy? Otherwise, maybe the classes in this model correspond to classes in source code, written in an object-oriented language like Java or C# and that the diagram is aimed to give insight in the relationships among these classes.
Why is Customer-Order and Customer-Credit Card an association and not aggregation like Customer-Address?
Apparently, the author does not regard these relationships to be 'part-of' relationships. Maybe Customer does not have any reference to Orders or CreditCards in the source code. Maybe Address information belongs to the responsibility of class Customer, but Order and Credit Card information do not.
Why is Order-ItemOrder not composition given that ItemOrder would not exist without an Order?
Maybe the author only uses a subset of UML and does not use composition by convention. Maybe the author thinks the difference between aggregation and composition is not important to convey for the purpose of this diagram.
Why is ItemOrder-Item not aggregation?
Apparently, the author does not regard this relationship to be a part-of relationship. Maybe the author has reserved the aggregation type of relationship to represent one particular programming language construct, which is not used in this case in the source code. Maybe the author has the opinion that an interface can never be aggregated in another class.
By the way, the aggregation between ItemOrder and ShoppingCart is clearly wrong. I think the diamond should be on the other side of the relationship.
Simply forget about shared/composite aggregation. It does have a low semantics and just leads to futile discussions whether it's needed and where it's used right or wrong. Just use (and interpret) the association and multiplicity.
The (almost) only place where you could use aggregations in a meaningful way is in DB foreign key (force delete) and memory (free unused) management.
What practice is considered the best one when i have to translate an aggregation/composition of an UML Diagram drawn in Design Phase in implementation phase?
In many cases, when aggregation or composition has been used in a UML class diagram, it just means an association and doesn't have any additional meaning. So, the simple advice is: just translate an aggregation/composition of a UML design model to an association and implement it with suitable reference properties in the implementation (model).
You may want to read my article Really Understanding Association, Aggregation, and Composition.
As Thomas noted, I dont think there are any clear generally aplicable best practices. There's just so many different situations and different contexts which strongly affect selected approach.
Aggregations and compositions are analytical constructs and should not appear in design or implementation models very often, if at all.
What can be said is, that many people struggle to understand the meaning/semantics of aggregation/composition. Usually they tend to over-identify aggregations and compositions. These are in fact rather rare relationships within SW system models. Not every 1:N relationship is an aggregation.
I've always avoided using aggregation because it seems so subjective which one-to-many relationships should be classed as aggregations. But I'm reviewing a model produced by someone else in which aggregations are used for many-to-many relationships (as in: a course consists of several modules, a module may be part of several courses). That strikes me as plain wrong, but I can't find a definitive rule against it. What's the official ruling?
Two things:
Are shared aggregations allowed? According to the UML spec, yes.
Is it useful in practice? Generally I'd say no.
I am not a fan of the UML Aggregation relationship. Whilst ownership is intuitively appealing, it is too subjective practically. I don't use it, and generally don't recommend it be used (although see footnote). Instead, focus on the important questions:
What's the cardinality?
What's the create/delete behaviour?
Why does the relationship exist? (i.e. what business fact/rule is the relationship capturing?
All above can be done with straight associations. If the answer is (a) it's one to many, (b) the 'one' end is responsible for creating/deleting the 'many' end and (c) you really want to, then use the Composite association. Aggregation however doesn't generally improve readability of the model, it adds confusion and detracts from surfacing the underlying domain rules/requirements.
hth.
footnote: there is one scenario where Aggregation does have well-defined semantics and can be useful. Specifically, if you have a recursive relationship, Aggregation says the resultant object structure is acyclic (i.e. a DAG). Downside is relatively few people realise that property - certainly not business domain experts. So you typically have to highlight anyway, e.g. in a comment / constraint.
A good website for this is
http://www.uml-diagrams.org/class-diagrams.html
If you search there for "Shared and Composite Aggregation" you will read, that shared parts can be modeled as aggregations. Even if the composite holding the part will be discarded the parts are allowed to survive.
This seems to make many to many relationships possible. For example sharing a part of a view for several view-components. Why not...
Personally this matches my understanding, that UML is very interpretative.
Let's set the terms. The Aggregation is a metaterm in the UML standard, and means BOTH composition and shared aggregation, simply named shared. To often it is named incorrectly "aggregation". It is BAD, for composition is an aggregation, too. As I understand, you mean "shared".
Again, if we'll look at the UML standards (look for Superstructure documentation there), we'll find, that "Precise semantics of shared aggregation varies by application area and modeler." So, ANY strategy you choose is acceptable. And you even can use different strategy for different projects.
But the shared aggregation IS useful and CAN be used with multiplicities on both sides and even the empty diamond can be on both sides.
The association in UML is an abstraction, that can be realized in any language and in any way, only the realization must be up to the diagram.
Such association, as on the diagram, can be realized as following:
Every instance of Student has a list of courses he is registered to,
and every instance of Courses has a list of registered
students/participants.
But this is not the only way of realization. There could be arrays instead of lists, and even somebody can make it without any normal collection at all - simply using the addresses in memory in C++.
Of course, we could draw two associations, one for student's list of courses and the second for courses' list of students. But thus:
our diagram becomes more complex and, therefore, less readable.
we are describing thoroughly the elementary things that any coder will do anyway in 99% cases.
we are limiting the freedom of coders. And in 1% of cases they'll have to choose between not following the diagram and not coding effectively. It is simply not your job.
So, do as you wish. Forbidden is only to change the strategy during one project and to FORBID others to use their only strategy.