Just to remind people, by qualified association we mean associations that look-like:
) states on page 146 that:
Qualifiers have some fairly deep semantics, and there are a number of complicated
fringe cases in which you'll find them. However, most of the time, the circumstances
for which you'll need qualifiers are pretty straightforward. If you can devise a lookup
data structure at one end of an association (for example, a hash table or b-tree), then manifest that
index as a qualifier. In most cases, the source end's multiplicity will be many and the
target end's multiplicity will be 0..1.
The book doesn't elaborate on these "fringe cases". (Sadly the book has no bibliography either...)
- Does anybody here know of any of these "fringe cases"?
- I'd be grateful to see any examples of qualified associations that do not have a * cardinality on the source end and a 0..1 cardinality on the target end that people have.
- Have you uncovered any other problems with qualified associations?
Any help clearing these "nasty surprises" would be appreciated.
[first example deleted cause it was wrong. Never answer a question while taking cold medicine --WilliamGrosso
An examples for (2) would be my amazon shopping cart. This contains an array (I'm guessing) of ISBN numbers of things I want to buy. The ISBNs are, in essence, the qualifiers that are used to lookup book particulars. But the books themselves are sort of prototypes objects ala the TypeObject
The book of the SyntropyMethodology
has a detailed description of what the qualifier might be for, and how you'd interpret different cardinalities, with examples.
One question that arises is to what extent a qualifier is just an index, and therefore only appropriate to a detailed design model. Thus, in your example, a "pure" analysis model might make acctNo a property of the BasicAccount?
type, and make the association a simple one. I try to restrict the use of qualifiers to the case where the qualifier "only makes sense" in the context of the source type: I see it as making a strong statement about which type encapsulates this data.
Also, in your example, I don't understand the * at the Customer end. I interpret this as saying that each BasicAccount?
is associated with many Customers, which seems wrong. Certainly this is the SyntropyMethodology
interpretation -- DaveCleal
I can see why having the * on the Customer end is a bit silly, but after scrutinising
book I still can't see anything technically wrong with
it. The 0..1 cardinality on the target side seems quite reasonable
though - this is
shown in the Syntropy book (p.37 text, p.38 OMT diagram).
I don't think there is anything technically wrong with the *. A qualified association is implicitly defining a pair of functions (one each way). The * means that if you navigate from Account to Customer you get a set (which might be empty). I don't think the SyntropyMethodology book is explicit about this. The 0..1 on the other end is entirely reasonable. The cardinality must always allow 0 if the domain of the qualifying parameter is infinite (e.g. date, number). It can be exactly 1 for qualifiers of restricted domain. -- JohnDaniels
If I replaced the * on the source side with a "1..4" that would be a reasonable
state of affairs for modelling a qualified association in which
all customers have at most one basic account, but up to four people are
referencing the same (joint) bank account.
With hindsight, * was also a bad choice because it would allow bank accounts
to exist that have no corresponding customer - I'm no banking expert, but
I find that hard to believe.
et al find a use for qualified associations in analysis.
The OMT book has a good example in chapter 3 (see under "3.3.6 Aggregation") a company can be listed on several stock exchanges under different ticker symbols.
Access to a company through a stock exchange must be qualified by a ticker symbol.
If access is made unqualified by making the ticker symbol an attribute of the company,
then you can't express the fact that a single company can be represented
on many stock exchanges under different ticker symbols.
(You can if you use a constraint, but it's visually more messy. I discussed using qualified associations conceptually in AnalysisPatterns
, in the last chapter. --MartinFowler
Why not put the ticker symbol in an association class?
The company is a function of the exchange and
the ticker symbol.
I'm getting somewhere with these examples now, but I still haven't seen
any "fringe cases".
See also SingletonInUmlForJava
Reference to point (3):
Aggregation. The filled diamond is ok, but the open one has, in UML, ridiculously hazy semantics. If your plan is to eventually write software I would avoid this one - I bet it doesn't affect code generation in any of the tools.
Regarding Aggregation. The filled diamond is ok, but the open one has, in UML, ridiculously hazy semantics.
I bet it doesn't affect code generation in any of the tools.
The semantics of the filled diamond is mainly defined by the following well-formedness rule from the UML 1.5 spec:
self.aggregation = #composite implies self.multiplicity.upperbound = 1
The OCL expresses that An Instance may not belong by composition to more than one composite Instance.
On page 2-66 the spec further clarifies: ... the composite object is responsible for the creation and destruction of the parts.
There is indeed no absolute consensus on the semantics of the open diamond. The spec says on page 2-66 that ''the semantics
of a shareable aggregation does not imply deletion of the parts when an aggregate referencing it is deleted.''
This conflicts with the common practice of data modelers: http://www.agiledata.org/essays/umlDataModelingProfile.html#Relationships
They use the open diamond to express cascade delete behavior from the whole to the part. They do not use the filled diamond because it would imply that the part cannot be contained by more than one whole. I agree that the spec prescribes no semantic difference between ordinary associations and aggregations (hollow diamond) but the data modeling community seems to be happy with their interpretation...
Finally, regarding the semantics of qualified associations: the UML1.5 spec is quite surprising... Again on page 2-66 you can read: ''In the case of multiplicity 0..*, it has no real semantic consequences but suggests an implementation that facilitates easy access of
sets of associated instances linked by a given qualifier value.'' This could indeed be realized with a map with as key the type of the qualifier and as value a list of references to the associated objects but I'm not sure this is always desirable... a precompiled database query may do the job very well. Also, not every conventional map from A to B using key C should be visualized as a qualified association since C is not always an attribute of B. Due to this mismatch in two directions, I've also been looking a long time for models where qualified associations add fundamental insight in the system. In the end, I started using them in logical data models (LDMs). In a LDM, I only mark natural keys that have a system-wide scope as primary keys of entities (e.g. passport_number for Person). If entities have additional keys that are only valid within the scope of a relationship to another entity, I model them as qualifiers of qualified associations (e.g. universitary_id for Person, on http://ironbark.bendigo.latrobe.edu.au/courses/subjects/softeng/2004s2/lectures/lecture09.html#Qualified%20Associations
there's an example of when I would use a qualified association in a LDM.)
I think using UML for data modeling is a bad idea. It's just the wrong tool for the job. Much better languages exist, including ObjectRoleModeling
has very good tool support in Microsoft Visio which is widespread in industry, while HERM is a little bit more on the academic/leading edge research side. I'd be worry to introduce students to an ad-hoc layer on top of UML by Scott Ambler for the purpose of data modeling. Some limitations of UML for data modeling are described in the link from ModernDinosaur
, and Terry Halping also has a series of articles discussing the problems of uising UML for data modeling. --CostinCozianu
What does the code look like for one of these?
The interface would be a method on the source type, returning either an instance of BasicAccount?
or a null reference. This method would take a single integer parameter - an account number.
The implementation behind this might be a dictionary keyed (in the example) on acctNo. For me, this implies that the Account does not know its number.
In Smalltalk, one might give Customer an instvar called accounts to hold the dictionary, then write
accounts := Dictionary new.
^accounts at: anInteger ifAbsent: [nil]
Customer>>accountAt: anAccount put: anInteger
accounts at: anInteger put: anAccount
A similar implementation is shown in UmlDistilled (see page 92). It shows a java.util.Dictionary object being referenced as a private member of the class on the source side (Customer) of the attribute.
Regarding, the open one has, ridiculously hazy semantics
- we need things with hazy semantics. Too much precision is not a good thing. There are times when you need to say, "this thing can get a message to that thing, but I don't know exactly how, or else we don't want to constrain it just now". Ditto aggregation. Booch added "uses" relation back in 1994 for just this reason. I shall be quite distressed on the day that there is no way to express things loosely. It is not the case that we always want to generate code from the drawings. --Alistair
Alistair, we shall certainly miss you at this year's EuroPLoP - paul
Drink a "Pfluemli" (plum schnapps) or Kirsch for me :-) -A.
I am curious if this qualified association notion is just about the notion of foreign keys? /Jidtima