9.16. Attributes
It is useful to identify those attributes of conceptual classes that are needed to satisfy the information requirements of the current scenarios under development. An attribute is a logical data value of an object.
Guideline: When to Show Attributes?
Include attributes that the requirements (for example, use cases) suggest or imply a need to remember information.For example, a receipt (which reports the information of a sale) in the Process Sale use case normally includes a date and time, the store name and address, and the cashier ID, among many other things.Therefore,
- Sale needs a dateTime attribute.
- Store needs a name and address .
- Cashier needs an ID .
Applying UML: Attribute Notation
Attributes are shown in the second compartment of the class box (see Figure 9.19). Their type and other information may optionally be shown.
Figure 9.19. Class and attributes.
More Notation
The full syntax for an attribute in the UML is:
visibility name : type multiplicity = default {property-string}
UML class diagram notation p. 249, and also on the back inside cover of the book Some common examples are shown in Figure 9.20.
Figure 9.20. Attribute notation in UML.
[View full size image]
Guideline: Where to Record Attribute Requirements?
Notice that, subtly, middleName : [0..1] is a requirement or domain rule, embedded in the domain model. Although this is just a conceptual-perspective domain model, it probably implies that the software perspective should allow a missing value for middleName in the UI, the objects, and the database. Some modellers accept leaving such specifications only in the domain model, but I find this error-prone and scattered, as people tend to not look at the domain model in detail, or for requirements guidance. Nor do they usually maintain the domain model.Instead, I suggest placing all such attribute requirements in the UP Glossary, which serves as a data dictionary. Perhaps I've spent an hour sketching a domain model with a domain expert; afterwards, I can spend 15 minutes looking through it and transferring implied attribute requirements into the Glossary.Another alternative is to use a tool that integrates UML models with a data dictionary; then all attributes will automatically show up as dictionary elements.
Derived Attributes
The total attribute in the Sale can be calculated or derived from the information in the SalesLineItems . When we want to communicate that 1) this is a noteworthy attribute, but 2) it is derivable, we use the UML convention: a / symbol before the attribute name.As another example, a cashier can receive a group of like items (for example, six tofu packages), enter the itemID once, and then enter a quantity (for example, six). Consequently, an individual SalesLineItem can be associated with more than one instance of an item.The quantity that is entered by the cashier may be recorded as an attribute of the SalesLineItem (Figure 9.21). However, the quantity can be calculated from the actual multiplicity value of the association, so it may be characterized as a derived attributeone that may be derived from other information.
Figure 9.21. Recording the quantity of items sold in a line item.
[View full size image]
Guideline: What are Suitable Attribute Types?
Focus on Data Type Attributes in the Domain Model
Informally, most attribute types should be what are often thought of as "primitive" data types, such as numbers and booleans. The type of an attribute should not normally be a complex domain concept, such as a Sale or Airport .For example, the currentRegister attribute in the Cashier class in Figure 9.22 is undesirable because its type is meant to be a Register , which is not a simple data type (such as Number or String ). The most useful way to express that a Cashier uses a Register is with an association, not with an attribute.
Figure 9.22. Relate with associations, not attributes.
Figure 9.23. Don't show complex concepts as attributes; use associations.
Guideline Relate conceptual classes with an association, not with an attribute. |
Data Types
As said, attributes in the domain model should generally be data types ; informally these are "primitive" types such as number, boolean, character, string, and enumerations (such as Size = {small, large}). More precisely, this is a UML term that implies a set of values for which unique identity is not meaningful (in the context of our model or system) [RJB99]. Said another way, equality tests are not based on identity, but instead on value.[6] For example, it is not (usually) meaningful to distinguish between:
[6] In Java, for example, a value test is done with the equals method, and an identity test with the == operator.
- Separate instances of the Integer 5.
- Separate instances of the String 'cat'.
- Separate instance of the Date "Nov. 13, 1990".
By contrast, it is meaningful to distinguish (by object identity) between two separate Person instances whose names are both "Jill Smith" because the two instances can represent separate individuals with the same name.Also, data type values are usually immutable. For example, the instance '5' of Integer is immutable; the instance "Nov. 13, 1990" of Date is probably immutable. On the other hand, a Person instance may have its lastName changed for various reasons.From a software perspective, there are few situations where one would compare the memory addresses (identity) of instances of Integer or Date ; only value-based comparisons are relevant. On the other hand, the memory addresses of Person instances could conceivably be compared and distinguished, even if they had the same attribute values, because their unique identity is important.Some OO and UML modeling books also speak of value objects , which are very similar to data types, but with minor variations. However, I found the distinctions rather fuzzy and subtle, and don't stress it.
Perspectives: What About Attributes in Code?
The recommendation that attributes in the domain model be mainly data types does not imply that C# or Java attributes must only be of simple, primitive data types. The domain model is a conceptual perspective, not a software one. In the Design Model, attributes may be of any type.
Guideline: When to Define New Data Type Classes?
In the NextGen POS system an itemID attribute is needed; it is probably an attribute of an Item or ProductDescription . Casually, it seems like just a number or perhaps a string. For example, itemID : Integer or itemID : String .But it is more than that (item identifiers have subparts), and in fact it is useful to have a class named ItemID (or ItemIdentifier ) in the domain model, and designate the type of the attribute as such. For example, itemID : ItemIdentifier .Table 9.3 provides guidelines when it's useful to model with data types.
Guideline |
---|
Represent what may initially be considered a number or string as a new data type class in the domain model if:
|
- The item identifier is an abstraction of various common coding schemes, including UPC-A, UPC-E, and the family of EAN schemes. These numeric coding schemes have subparts identifying the manufacturer, product, country (for EAN), and a check-sum digit for validation. Therefore, there should be a data type ItemID class, because it satisfies many of the guidelines above.
- The price and amount attributes should be a data type Money class because they are quantities in a unit of currency.
- The address attribute should be a data type Address class because it has separate sections.
Applying UML: Where to Illustrate These Data Type Classes?
Should the ItemID class be shown as a separate class in a domain model? It depends on what you want to emphasize in the diagram. Since ItemID is a data type (unique identity of instances is not used for equality testing), it may be shown only in the attribute compartment of the class box, as shown in Figure 9.24. On the other hand, if ItemID is a new type with its own attributes and associations, showing it as a conceptual class in its own box may be informative. There is no correct answer; resolution depends on how the domain model is being used as a tool of communication, and the significance of the concept in the domain.
Figure 9.24. Two ways to indicate a data type property of an object.
[View full size image]
Guideline: No Attributes Representing Foreign Keys
Attributes should not be used to relate conceptual classes in the domain model. The most common violation of this principle is to add a kind of foreign key attribute , as is typically done in relational database designs, in order to associate two types. For example, in Figure 9.25 the currentRegisterNumber attribute in the Cashier class is undesirable because its purpose is to relate the Cashier to a Register object. The better way to express that a Cashier uses a Register is with an association, not with a foreign key attribute. Once again, relate types with an association, not with an attribute.
Figure 9.25. Do not use attributes as foreign keys.
[View full size image]
Guideline: Modeling Quantities and Units
Most numeric quantities should not be represented as plain numbers. Consider price or weight. Saying "the price was 13" or "the weight was 37" doesn't say much. Euros? Kilograms?These are quantities with associated units, and it is common to require knowledge of the unit to support conversions. The NextGen POS software is for an international market and needs to support prices in multiple currencies. The domain model (and the software) should model quantities skillfully.In the general case, the solution is to represent Quantity as a distinct class, with an associated Unit [Fowler96]. It is also common to show Quantity specializations. Money is a kind of quantity whose units are currencies. Weight is a quantity with units such as kilograms or pounds. See Figure 9.26.