| Stephen R. Palmer | Software Development | www.step-10.com |
| Home | Design | Process | Tools | Books | About |
|
|
Modelling in Colour: Using the DNCThe Domain Neutral Component can really help speed up the building of outline object models of our problem domains. The way we do this is to begin by looking for some Moment-Intervals in our problem domain. Then we overlay the Domain Neutral Component and start replacing the domain neutral names with names specific to our problem domain. Where we do not need classes from the domain neutral component we drop them out to simplify our model. Lending Library ExampleA basic lending library is a nice simple example that we can use to illustrate this. First we need our Moment-Intervals. Borrowing a book is the most obvious event or activity at a library but to be able to borrow books we need to first register as a member of the library. So lets use Registration as our first Moment-Interval, and overlay the Domain Neutral Component.
Now we start to replace the domain neutral names in the diagram with names from our lending library domain. We consider each of the Party, Place and Thing legs in turn starting with the Party leg. Party LegWe need to ask what people and organizations are involved in the Registration Moment-Interval and in what ways they are involved. To keep our example simple we will assume our library only lends to individual people and does not have special memberships for organizations or shared memberships for families. Someone that registers to become a member of the library enters into a contract with the library. More accurately the contract is between the member and the organization that provides the library service. So we have people playing the role of members and an organization playing the role of library service provider. If we assume that it is this organization that wants the software for which we are building the object model, then the roles being played by that organization can be left as implicit in our model. This means we can replace the PartyRole class from the Domain Neutral Component with a more specific Member class, the Party class with a more specific Person class, and the PartyDescription class with a PersonDescription class.
If we needed to include the organization offering the library service we would need to duplicate the party leg with a LibraryServiceProvider Role class, an Organization Party class and a OrganizationDescription class. In fact we could have many party roles involve in a Moment-Interval. For now we will assume we only need to model the Person registering as a Member. Place LegOur Registration Moment-Interval enables the borrowing of books from the library. If we ignore, for a short time, the possibility that our library is a mobile or virtual library, we can assume that the library is located in a building of some kind. Therefore, we have some type of building playing the role of being a library in our Registration Moment-Interval. That means we can replace the PlaceRole class in the DNC with a domain specific Library class, the Place class from the DNC with a Building class, and the PlaceDescription class with a BuildingDescription to indicate the kind of building in which the library is located.
Thing LegThe act of registering creates a membership account for that person at the library. The Thing class therefore becomes a MembershipAccount class and the ThingDescription becomes an AccountDescription class. The Domain Neutral Component suggests that we might need a role class for our MembershipAccount to encapsulate the attributes and operations that are specific to the way the MembershipAccount class participates in the Registation MomentInterval. Without an obvious name for this role in the domain we give that role class the name AccountInRegistration. ResponsibilitiesNow lets consider the typical responsibilities suggested by the class archetypes. We need to compare these suggested responsibilities with the functional requirements for the software. Where there is no need for a particular responsibility we simply omit it. In doing this analysis we frequently find that a class ends up with no responsibilities. In this case we remove the class from the model. This helps us produce the simplest object model that will handle the job well. The MI-Detail class is responsible for remembering the quantity of a kind of thing involved in the Moment-Interval and for calculating subtotals. Each Registration Moment-Interval only ever opens a single account so we can drop the MI-Detail class from our model connecting the Registration class directly to the AccountInApplication role class. Although the stereotype tag is a convenient UML mechanism for
indicating the archetype of a class, it does hide some very important meaning
in a rather plain and simple text label [Coad99].
... Fortunately the UML standard [OMG] does rather begrudgingly allow us an
alternative: colour. The AccountInApplication class is responsible for encapsulating the information and behavior specific to the way a MembershipAccount object participates in a Registration. Unless we have some attributes and operations to place in this class it is redundant and we can drop it form the model too. Description classes are typically responsible for describing groups of objects that have a set of values in common, for finding members of this group that are available to perform a particular role in a particular moment-interval, and for assessing the performance of the group of objects as a whole. The AccountDescription class could be responsible for defining the values of different types of membership. Its objects might, for example, be responsible for knowing how many books can be borrowed concurrently by people with the membership accounts it describes. It might restrict the types of books being borrowed so that people holding child membership accounts cannot borrow adult-only books. On the other hand, if we only have one type of membership at our library we do not need a Description class to distinguish between the different types and we can drop the class from the model. Also we actually have a 1-1 relationship between the Registration class and the MembershipAccount class. A person always registers once to open a membership account. Every membership account needs a registration to create it. There is a general principle that a 1-1 association between classes offers the opportunity to collapse the two classes at the ends of the association into one class. There may be a good reason for keeping the responsibilities split between two classes but when there is not, the simpler model is preferable. [Coad 97]. Therefore, lets collapse the MembershipAccount class into the Registration class.
The PersonDescription class is trying to categorize people. People can be grouped by age range, gender, martial status, ethnic background, nationality, citizenship, and so on. For each categorization we need to add a separate Description class. Description classes often end up as little more than simple sets of enumerated values. Categorization of people can also be a sticky ethical and legal subject. If we discover our library service provider needs no more than basic name and contact information about their members then we can drop the PersonDescription classes altogether. A similar argument applies to the BuildingDescription class. If there is no requirement to know what type of building a library is located in we can drop that class. Also if our client is only interested in the buildings containing their libraries and no interest in any other use that is made of the building then we have a 1-1 relationship between our Library class and the Building class and can collapse the two classes into one. When Place and Thing classes are collapsed together with their role classes we tend to leave the result as a Party, Place or Thing class. This reflects that idea that the place or thing has been constructed or purchased for one and only one purpose. Therefore we end up with a single Party, Place, or Thing class we call Library.
If we discover that our library service provider has only one library and has no intention of opening another library we end up with a 1-1 relationship between the Library class and the Registration class. If there is only one Library that can be involved in the transaction we can leave that as implicit in our model and remove the Library class. Also if a person only ever needs to register once at the library to become a member for life then we have a 1-1 association between the Registration class and the Member class and we can collapse the Registration class into the Member class. We are now left with a very simple two class model with the Person class responsible for uniquely identifying the real world person who holds the membership and the Member class that is responsible for holding the membership information such as late fee balance and membership number. When an application or registration process is very simple like this, the model often reduces in this way. We can collapse the model even further to a single Member class. This might be appropriate in a web-based system for consumers where the same person can register multiple times and it is not practical or important enough to have a single view of all of a person's dealings with the company. Obviously this an extreme example and more complex business processes require all or nearly all of the classes in the DNC pattern. Reviewing Existing Object ModelsAnother way to use the Domain Neutral Component is to help review and restructure existing object models. Colouring In Object ModelsThe basic technique involves 'colouring in' the classes in the model by assigning them to class archetypes and then comparing the result to the Domain Neutral Component. When working with printed diagrams we can literally colour in the classes using pink, yellow, green and blue highlighter pens. Most modeling tools allow us to set the background color of a model element and the stereotype tag. If the 'UML in colour' profile is switched on, Borland Together 2006 automatically sets the background color when we select the archetype name in the stereotype property of a class. The first question of course is given a class what archetype should it be given. Peter Coadl suggests asking the following questions in order until you either answer yes or reach the end [Coad 99]
Lets illustrate this with an example using the following simplified
object model of flights and airports as an example. Model to be reviewed We take each class in turn and ask the four questions in turn until we have an answer.
Comparing with the DNCNow that we have 'colored in' our object model we play 'spot the difference' with the Domain Neutral Component. Challenge Multi-colored InheritanceAn immediately obvious difference is the inheritance relationship between Person and its subclasses Pilot and Passenger. In the DNC, Role classes are associated to their role-player class; they do not inherit from it. Inheritance is an extension mechanism. An object of a subclass is the same kind of thing as an object of its superclass but our object model has the Passenger and Pilot as different kinds of things, different archetypes, from their Person superclass. Why is this a problem? Imagine what happens if one of our pilots wants to be a passenger on a flight he or she is not actually piloting. We have three options, all of them bad:
The Domain Neutral Component suggests we relate the Person class to its role classes using a simple association. This gives our Person objects the ability to play neither, either or both of the Passenger and Pilot roles over time without the need for objects to change from one class to another or duplication of information or responsibility. We would probably want to check that a pilot on a flight has not booked a passenger seat for himself on the same flight but checking for conflicts in role being played is an archetypal responsibility of the role-player class so that fits very nicely into our overall pattern. Another conclusion we can draw from this is that we need to challenge multi-colored inheritance relationships; inheritance relationships where the class on one end belongs to a different archetype to the class on the other end. Look for Missing Place and Thing RolesThe Domain Neutral Component suggests that there may be a need for Role classes between Moment-Interval classes and Party, Place, or Thing classes. Our colored model has the Flight Moment-Interval class associated directly to a Place Airport class. Are we missing a role class in between? Each object of the Flight class is related to two objects of the Airport class; the airport from which the plane takes off and the airport at which it subsequently lands. There are therefore two different roles being played by the airport objects; those of departure airport and arrival airport. If there are differences in the responsibilities of these two roles then we might want to add classes to model these two Roles. The airport class is responsible for allocating runways for a flight to take off from and land on. This presumably works differently depending on whether the flight is arriving or departing. You certainly do not want to be taking off from a runway when another plane is about to land on it. We can split the responsibility between the two roles making the departure airport role responsible for allocating a runway for a flight to take of from, and making the arrival airport role responsible for allocating a runway for a flight to land on. The roles can also split the handling of performance assessments such as counting the number and percentage of flights taking off on time and landing on time; a nice partitioning of responsibilities.
In general, if there is behavior specific to the way a Party, Place, or Thing object participates in a Moment-Interval then it may be useful to separate that behavior out into a Role class played by the a Party, Place, or Thing class. Of course, we might find that we genuinely do not need the level of partitioning or specificity provided by a role class and the simpler model does the job perfectly well without the additional complexity of another class. Classes of the Party archetype nearly always play multiple different roles in a system. Place classes often play multiple roles but Thing classes tend not to play multiple roles very often. This is because Things are normally created and purchased to serve one purpose and one purpose only. Therefore a Thing is most likely to only perform one role and the responsibilities of that role can be collapsed into the Thing class itself. So, in conclusion, challenge associations from Moment-Interval (and Moment-Interval Detail) classes directly to Party, Place, or Thing classes and ask if there should be a yellow Role class between the pink Moment-Interval and green Party, Place, or Thing class. SummaryThe Domain Neutral Component is an archetypal pattern for object models. We can rapidly build robust, flexible object models by identifying Moment-Intervals in our problem domain, overlaying the Domain Neutral Component, replacing the domain neutral names with domain specific names and removing responsibilities and classes where we do not need that level of specificity. Existing object models can be improved by assigning their classes to class archetypes and comparing the result with the Domain Neutral Component. In particular, we challenge any inheritance relationships that have classes belonging to different archetypes participating in the relationship. We also challenge associations directly between Moment-Interval classes and Party, Place, or Thing classes, asking if a Role class is needed in between. From UML Association to DNCKarl Frank, a colleague until recently 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.
|
More on... |