Karl Frank, a great colleague of mine at both TogetherSoft and
Borland, and I were in Denver, USA, giving a modelling in colour
workshop for a client. One evening Karl asked me what if any
relationship I thought there was between roles in the Domain Neutral
Component (DNC) and role labels on a UML association. The subsequent
discussion led to the following progression of thought that starts with
a plain old UML association and ends up with the Domain Neutral
UML associations in UML 2.0 can be complex little beasts. For this discussion it is sufficient to remember the following points:
- In a UML class diagram, an association is drawn as a solid line linking two class symbols.
- We draw associations to show objects of one class are related in some way to objects of another class.
- A multiplicity at the end of an association indicates the number of objects of that class that may be related to a single object of the other class.
- We can label the association with the name of the relationship it represents.
- We can also indicate the role played by the objects of each class in the relationship.
The diagram below shows an association drawn between two classes with label, roles and multiplicities.
Figure 1: UML Association
Employment is a useful example. Employment is a relationship between a person and an organisation. We can model this in UML two classes Person and Organization connected by an association. A label on the association makes sure we know the kind of relationship that the association represents.
As we analyse and add detail to the relationship we ask ourselves the following six questions:
- How many organisations can a person be employed over time?
- How many organisations can a person be employed at any one time?
- How many people can an organisation employ over time?
- How many people can an organisation employ at any one time?
- What role in the relationship does the organisation play?
- What role in the relationship does the person play?
The answers to the first four questions enable to us to add multiplicities to the ends of the association. The answers to the last two questions enable us to add role labels to the ends of the association.
Employment is a many to many association because an organisation may employ many people and a person may work for more than one organisation either. Objects of the organisation class play the role of employer and objects of the Person class play the role of employee in the relationships.
Figure 2: Person and organisation classes linked by an employment association
Frequently we are interested in more information about a relationship than just its name and the name of the roles played by the participants in that relationship. In our example of employment, we may be interested in the start date and end date, if any, of the employment relationships We may also need to know the annual salary, the total paid to date this year, and so on.
Currently our model only has two classes in which we can define the
attributes and operations needed to handle these requirements. If we
define these attributes and operations in the Person class we need to
duplicate the attributes for each additional job held by a person and
somehow have the operations of the class match each set of attributes
to the appropriate job.
Figure 3: Not a good way to model salaries
Trying to define these attributes and the operations in the organisation class is even worse because large organisations employ thousands of people. No, these attributes and operations are specific to the relationship itself. What we need is a class that models the relationship.
Lets introduce an Employment class to our previous model. Now each employment object is related to precisely one organisation object and one Person object (indicated by the multiplicities of 1). Person and organisation objects may be related to many Employment objects.
Figure 4: Introducing a class to represent a type of relationship
This idea of introducing a class to represent a relationship is so common that UML has a special piece of notation for it called an association class.
Figure 6: Association class notation in UML.
The association class notation has the advantage of clearly distinguishing between classes that represent relationships and classes modeling other concepts. Also adding an association class does not disturb the original association between the classes to which it relates. However, the notation has a number of disadvantages:
- It is another piece of notation to learn and remember.
- It is largely redundant; we already have stereotypes as a mechanism for distinguishing different kinds of classes.
It can convey the impression that classes representing relationships are subordinate to the other classes in the model when it is the interactions and transactions of a relationship that are the most important part of the domain. After all in business interactions and transaction is where the money is made and spent.
Finally, the association class notation is not part of a cohesive scheme for distinguishing the major different types of concept modeled by classes in a typical object model. For example, there is no equivalent special role class notation in UML but it is almost as common to want to record and manipulate information specific to a particular role being played in a relationship as it is to want to do so for relationships themselves.
We can apply the same sort of logic that we used to derive the need for a class representing an association to derive the need for classes to represent the roles being played in the relationship.
Figure 7: Introducing classes to model the roles in a relationship
Our example now has three different kinds of class; those representing parties, those modelling relationships and those modeling roles. If we assign a stereotype to represent each of these three different kinds of class then we can already see the DNC pattern starting to emerge.
Figure 8: Stereotype assigned to indicate the kind of class
Employment is an example of a relationship that lasts for some interval of time. Other relationships between parties are no more than momentary interactions. A simple example of the latter is that of a sale of some items to a consumer by an organisation. In this case the role played by the organisation is that of a vendor and the role played by the person is that of a customer. Examining what is being modelled by the classes representing relationships more often than not we find they actually represent some significant interaction between two or more parties, places or things that takes place in an instant of time or over a period of time. In other words they tend to match what we call Moment-Interval classes.
In their book, Streamlined Object Modeling, Nicola, Mayfield and Abney concur with this idea of using separate objects to represent parties, roles and moment-intervals. They put it this way, "To model a person or organization that can participate in a system, use an actor object. Model the participation and actions of the person or organization with separate objects."
Knowing participating parties tells us who is involved in a Moment-Interval. However, many times it is just as important to know where a Moment-Interval happened. For example, if we have multiple stores we may need to know at which store a sale was made. Now we have a relationship between the parties in the transaction and the place at which the Moment-Interval has occurred. The same argument of role and role-player applies to the place. In the case of a sale of goods to a consumer we have a building playing the role of a shop.
Figure 9: Sale place
Similarly, if we need them, we can add place classes to our employment example. The place leg of model could model the location at which the person is employed, the shop, branch, factory, state, region, or country.
Figure 10: Place of Employment
Now we have a model that captures who is involved in our Moment-Interval and where it takes place. However, in our sale example we are still missing what is being sold. We need to add some classes to represent the items that in the sale. Here there is a slight twist. Quite reasonably, there could be different quantities of different types of item involved. For example, a sale to a stereotypical computer programmer might consist of a large jar of instant coffee, several frozen pizzas, a box of chocolate bars, and a large number of cans of cola with higher than usual amounts of caffeine. Each of these different types of item have different product codes, different cryptic descriptions printed on the till receipt and, usually, different prices. We would like to encapsulate the attributes and operations of the parts of the transaction that deal with each type of item. We need to add a SaleItem class.
We could think of each object of the SaleItem class as representing one line on the printed receipt of the sale. Each SaleItem object is responsible for remembering the quantity of a particular type of item that was sold and for calculating the total price for the items it knows about. We also need a class to represent the products we are selling. This is obviously falls into the category of a catalogue-entry-like description class.
Figure 11: Adding the items sold to the model
In our employment model we might want to the items assigned to the employee for their use in performing their duties as an employee. These might include special tools, special clothing or simply a desk and chair.
Figure 12: Adding the items to be used to perform the duties of the employment
Notice again that the thing leg has a class representing Moment-Intervals details because of the different quantities of different types of item assigned to the employee. Why do we typically need MI-Detail classes for the thing leg and not for the place leg?
Generally a Moment-Interval occurs at a single specific place. The obvious exception to the rule is when a Moment-Interval represents the movement of someone or something from one place to another. So unlike the Thing leg where it is common for multiple things of different types to be involved, it is the general case that only one or two places are involved in a particular Moment-Interval.
In a class representing a moment of time, any MI-Detail objects are thought of as occurring at the same time as the Moment-Interval class of which they are part. For example all the SaleItem objects are considered sold at the instant in time that the Sale object to which they belong is considered sold.
Where a class represents an interval of time, any MI-Detail objects typically start at the same time as the Moment-Interval class to which they belong. For example, if we have a Moment-Interval representing the rental of a number of different movies from a DVD rental service, all the DVD rentals in a particular rental transaction have the same start time but popular or recently released DVD's may have to be returned before other DVD's.
Categories of parties, places and things
Our two example models now answer the questions of who, where and what are involved in our Moment-Intervals. Comparing this with model with the domain neutral component we notice that we have all four archetypes are represented and there is only a little more generalisation to be done to arrive at the full DNC pattern. We already have a description class archetype for the kinds of things being sold in the sale example. In the Employment example it would be quite reasonable to categories the organisations in some way, by industry type for example, and to categories places in some way, by building type for example. Therefore a general model pattern does justify having description class archetypes on each leg of the DNC.
It is this natural expansion of a relationship between parties,
places and things that gives us the confidence that the domain neutral
component is in fact a firm foundation around which we can build our