Conceptual Modeling - Object-Oriented Analysis and Design for Information Systems: Modeling with UML, OCL, and IFML (2014)

Object-Oriented Analysis and Design for Information Systems: Modeling with UML, OCL, and IFML (2014)

CHAPTER 6

Conceptual Modeling

Fundamentals

This chapter presents the basic elements of conceptual modeling with the UML class diagram. There is a detailed discussion of the three main elements of a conceptual model: concepts, attributes, and associations. It covers best practices on how to use those elements so that models are kept clear and maintainable. The chapter also gradually presents OCL (Object Constraint Language), especially in order to define derived attributes and derived associations, as well as class invariants, which improve significantly the quality of a conceptual model. Finally, the chapter discusses the organization of the conceptual model; inheritance is not the only structure than can be used: it is best suited for representing concepts that are structurally related, but associative roles and modal classes should also be used to represent different kinds of organization that are not adequately described by inheritance. The chapter also shows how to discover and refine conceptual elements in detailed use cases and system sequence diagrams, therefore making the connection between those analysis artifacts.

Keywords

Conceptual model; class diagram; attribute; association; inheritance; OCL; invariant

Key Topics in this Chapter

• Attributes

• Concepts

• Associations

• Collections

• Organization of the conceptual model: structural, associative, and temporal

• Invariants

• Iterative construction of the conceptual model

6.1 Introduction to conceptual modeling

Domain analysis consists of discovering and modeling information that has to be managed by the system. This means that the team should discover how the information has to be structured and transformed. It starts during Inception with the preliminary conceptual model and continues during Elaboration, when that model is refined and completed as requirements analysis is deepened with the expansion of use cases.

One can analyze two aspects of information: static (also called structural), which is studied in this chapter and Chapter 7, and functional, studied in Chapter 8. The static aspect may be represented in the conceptual model, and the functional aspect in the system operation contracts.

During analysis there is no dynamic model for the objects, because analysis takes into consideration only an external view of the system. The dynamic model, consisting of the collaborations among objects, is made during design (Chapter 9), because only at that time are internal aspects of the system addressed. Thus, the functional model of analysis indicates only what information enters and leaves the system, without saying how the information is transformed. Later, the dynamic model of design will show clearly how object collaborations could change information.

The conceptual model describes information that the system is going to manage. It is an artifact from the problem domain, not the solution domain. Therefore, the conceptual model should not be confused with the Design Class Diagram (DCD), which belongs to the software architecture (Chapter 9). The DCD, although initially derived from the conceptual model, belongs to the solution domain and therefore serves different purposes.

The conceptual model should not also be confused with the data model (Chapter 13), because the data model emphasizes stored data representation and organization, while the conceptual model aims at representing the comprehension of information by users, not its physical representation. Thus, a relational data model is just one of the possible physical representations of a more essential conceptual model.

An interesting way to comprehend the conceptual model is to imagine that the elements described by it correspond to information that initially exists only in the mind of the user, as represented in Figure 6.1, and not in a physical store system.

image

FIGURE 6.1 The conceptual model is a representation of the users’ view of the information.

A user sends information to the system and receives information from the system through system events and returns, respectively. At this point, the system does not even need to be considered a computationalsystem, because the information exists independently of computer support for storing and managing it.

The goal of the analysis is to study the problem. But the computational system is a solution, and therefore, it belongs to the design. The system solution could even be designed without computer technology. It is possible to analyze a whole situation and then propose a manual solution to implement it, in which, for example, data are stored in paper sheets, and operations performed by workers using pencil, eraser, and staplers.

Just like essential use cases, the conceptual model is independent of the physical solutions that could be adopted, and should contain only elements that belong to the domain of the problem, leaving to the design the elements of the solution, that is, all elements related to technology, such as interfaces, storage, communication, and so on.

The conceptual model represents only the static aspect of the information. Therefore, in the conceptual model, references to operations or dynamic aspects of the system cannot exist. Although the conceptual model is represented by the UML class diagram, the analyst should not yet include any methods. Chapter 9 shows how to identify and design methods using a systematic approach.

When the class diagram is used for conceptual modeling, there are precisely three kinds of elements to use for representing information:

Attributes: Simple alphanumeric or primitive information, such as numbers, texts, dates, etc. Examples of attributes in the Livir project are customer name, payment date, book title, and total value of an order. An attribute is always connected to a more complex element: the concept.

Concepts: The representation of the complex information that has coherent meaning in the domain. Concepts usually aggregate attributes and cannot be described merely as alphanumeric. Concepts also may be associated to each other. Examples of concepts in the Livir project are book, customer, order, and payment.

Associations: A kind of information that links different concepts. However, associations are more than mere links: they are information. In the Livir example associations should exist between orders and customer, and also between orders and books, for example.

These three elements are detailed in the next sections. It is practically impossible to explain one without mentioning the others, because the three are strongly interwined.

6.2 Attributes

Attributes are, in the conceptual model, the alphanumeric and primitive elements such as date, money, number, string, interval, etc.

Although most programming languages allow attributes to be defined as data structures such as lists, arrays, sets, trees, etc., it is not advisable in conceptual modeling because those structures are better modeled as associations, as explained in the following sections.

Complex concepts (classes) should also not be used as attributes of other concepts (although, again, programming languages allow that). For example, a book should not be an attribute of an order. If a relationship between books and orders exists, then an association should be used instead, because books and orders are complex concepts. An exception to this recommendation occurs when a primitive type (Section 6.2.5) or enumeration (Section 6.2.4) is used to label an attribute; primitive types and enumerations are defined as stereotyped classes, but they do not behave like concepts. They are used as attribute types. For example, a date is composed by parts such as year, month, and day, however a birth date is considered an attribute of a person, not a complex concept associated to a person.

Attributes in UML are always represented inside a class, as shown in Figure 6.2, where the class Customer has the attributes: name, id, address, and phone.

image

FIGURE 6.2 Attributes represented inside a class.

6.2.1 Attribute types

Attributes may have a type, although this is not mandatory for the conceptual model. Figure 6.3 presents a version of the class of Figure 6.2 with typed attributes.

image

FIGURE 6.3 Typed attributes.

Types in conceptual models have the same meaning they have in programming languages. In Figure 6.3, we have the classical type String, and primitive user-defined types IdNumber and PhoneNumber.

When an attribute is defined by formation rules, as in the case of id and phone, it is advisable to define a primitive type especially for it, as is done in Figure 6.3.

The address is something special. Is it an attribute or a complex concept? Is it simply a string or complex concept composed of street, ZIP code, number, city, etc.? This case, as many others, is decided by analyzing the information needs of the users. If addresses are used just to print envelopes and send mail, then they behave merely as strings, and may be represented as attributes typed as strings. However, if addresses are used to calculate distances and routes, or if they are used to group customers that live in the neighborhood, then they behave as complex concepts and should be modeled as a primitive type. Furthermore, if they have a structure of associations between them, then they should be modeled as complex concepts.

6.2.2 Initial values

An attribute may be declared with an initial value, that is, every time a new instance of the concept is created, that attribute will automatically receive a defined initial value, which can be changed later if necessary.

In the Livir system, an order may be created, for example, with a total value that is initially zero. This can be defined in the class diagram, as shown in Figure 6.4.

image

FIGURE 6.4 A class showing an attribute with an initial value.

The definition of an initial value for an attribute may also be created with the use of the Object Constraint Language (OCL) (Object Management Group, 2010).

Every OCL expression should be declared in a context that corresponds to a class. Most OCL declarations also have a subcontext, consisting of a class property, that is, an attribute, association role, or even a method. When declaring the initial value for the attribute totalValue in class Order, the context is Order and the subcontext is totalValue. Thus, the OCL expression starts as

Context Order::totalValue

Optionally, the type of the attribute may be added:

Context Order::totalValue:Money

In order to indicate that the OCL expression is defining an initial value for an attribute, the clause init: is used, followed by the expression that when evaluated produces the initial value for the attribute. As in the example the initial value is the constant 0, the expression may be defined as

Context Order::totalValue:Money

init: 0

The expression may also be simplified by omitting the type of the attribute:

Context Order::totalValue

init: 0

An attribute may have its initial value defined by more complex expressions. Later, examples of more complex OCL expressions are presented, which can be used to initialize attributes with values produced by mathematical and logical operations.

6.2.3 Derived attributes

Derived attributes are understood here as derived alphanumeric values only. If a “derived attribute” refers to objects or data structures, then they are called derived associations (Section 6.4.3). Derived attributes differ from normal attributes because they cannot be changed directly. In other words, they are read only.

A derived attribute is calculated and must be defined by an expression. In the class diagram, a derived attribute may be represented by a slash (/) preceding the attribute name (and type), followed by “=” and the (OCL) expression that defines the attribute. Figure 6.5 shows an example in which profit is defined as the difference between price and cost.

image

FIGURE 6.5 A class showing a derived attribute.

Derived attributes may also be defined by OCL expressions.1 The expression again has a class as context and an attribute as subcontext. It is followed by the word derive: this indicates that the expression that follows it defines how the value of the derived attribute is calculated. The expression of the example of Figure 6.5 defines profit by using the values of other two attributes of the same class: profit=pricecost.

For now, we can consider that the OCL expressions after clauses such as init: and derive: start with an expression that denotes an instance of the context class. That instance is referred to by the word self.

The notation self.property allows one to access the value of a property (attribute, association role, or method) belonging to the object. For example, in the context of the class Book, the expression self.cost denotes the value of the attribute cost of a given instance of Book.

Thus, the OCL expression that defines the derived value for the attribute profit of class Book is

Context Book::profit

derive:

self.price-self.cost

In OCL it is possible to omit the expression self when the context is not ambiguous. In the example above, the expression could be simplified to

Context Book::profit

derive:

price-cost

In the Book context, price and cost may be nothing else but attributes of Book. Then, the word self may be omitted from the expression.

Derived attributes may not be directly updated. In the Book class of Figure 6.5 only the attributes cost and price may be directly updated. The derived attribute profit is read only: it is calculated as the result of its defining expression.2

6.2.4 Enumerations

Enumerations are a balance between concepts and attributes. They are basically strings, and behave like that. But there is a predefined set of valid strings that constitutes the enumeration domain. For example, a calendar day can only assume a value in a set of seven possibilities: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, and Saturday. Thus, an attribute defined as a CalendarDay (typed with that enumeration) would only assume one out of those seven values.

Enumerations may appear in UML diagrams as stereotyped classes. It is suggested that enumerations that are domain independent are not placed in the same diagram that contains the conceptual model, but in a special package intended to contain the enumerations, as shown in Figure 6.6, because domain-independent enumerations (such as CalendarDay) are very reusable from application to application. Only domain-specific enumerations should be kept together with the other classes of the conceptual model so that people can see their meaning more easily.

image

FIGURE 6.6 Definition and use of an enumeration.

In Figure 6.6, the attribute validity of class Offer may have assigned to it one out of the seven possible values for the enumeration CalendarDay.

Enumerations may be considered stereotyped classes. While they may have associations and attributes of their own, the analyst is not encouraged to use those features because they could simply turn the enumeration into a complex concept and it would probably lose reusability. For example, consider the CalendarDay enumeration. It is simply a list of seven names. Suppose now that the analyst adds some attributes to the CalendarDay enumeration, such as, for example, the working hours. Then, for example, Monday to Friday may have working hours defined from 9 am to 5 pm, Saturday from 9 am to noon, and Sunday may have no working hours at all. Different applications could define working hours in a different way. In this case, what is the difference between this enumeration and a complex concept as it also has attributes and possibly associations and even methods later? Instead of creating attributes or associations for an enumeration it would be advisable to create a new complex concept that accommodates the enumeration and the other attributes. In the example, a new concept working day could be created with two attributes: calendar day (still an enumeration), and working hours (normal attributes as explained above). Thus, enumerations that are thought to incorporate extra functionalities should be maintained without that structure and included in normal classes.

To remain reusable, an enumeration should not be able to access another class through an association, but any other class should be able to access the enumeration. The fact that Offer in Figure 6.6 has an attribute labeled with CalendarDay allows the normal class Offer to access the enumeration CalendarDay but not vice versa. This keeps the enumeration uncoupled from the classes that use it and therefore it is reusable.

Enumeration values in OCL may be represented by the enumeration name followed by “:” and the value name, as, for example, CalendarDay::Tuesday.

6.2.5 Primitive types

The team can and should define primitive types when they deal with attributes that have formation rules, as in the case of ISBN. Primitive types may be defined as classes stereotyped with entprimitiveent, as shown in Figure 6.7.

image

FIGURE 6.7 Example of a primitive type.

The ISBN class, which is stereotyped in such a manner, is a type that can be used to define attributes. It is not a complex concept like Book, Customer, etc. It has a value with public access (marked with “+”), and a validation predicate that is private (marked with “−”), meaning that it can be accessed only by methods inside the class itself. That predicate can be called to verify if the ISBN value is valid or not, considering its formation rule.3 That predicate can be used in the constructor (the method that creates instances of the class) to guarantee that only valid ISBNs are created. Remember that conceptual classes do not have methods, but primitive types are not part of the conceptual model. They are user-defined, reusable low-level components.

Although the value of the primitive type has public access it is normally accepted that it is immutable. That means that the value of the primitive type can be defined only at creation time, and not updated later. This is to make it consistent with the idea of primitive data elements as constants, and not as objects. Objects may change their internal state, and constants usually do not.4

Some primitive types, such as Date and Money, are already available in some programming languages and database management systems. Other not-so-common types, such as ISBN, ZIP code, odd numbers, etc., may be created.

The primitive type formation rule must be defined syntactically, that is, by evaluating expressions that do not need to consult data managed by the system. If a formation rule depends on consulting attribute or association values, then it is not, probably, a primitive type, but a normal class. For example, the prime number formation rule may be checked without consulting objects and associations, but a registered customer name may not be a primitive type, because to check if a string is a registered customer name, it is necessary to query existing names of current customers.

A primitive type usually is application independent, that is, its meaning usually is independent from the system or project being developed. An ISBN has the same meaning and formation rule in any application domain that uses it. Concepts such as Customer, Book, and Order may have different definitions in different applications and cannot usually be reused without some refactoring effort. However, primitive types are usually 100% reusable, without adjustments or modifications.

6.3 Concepts

Concepts are more than alphanumeric values. They are also more than a bunch of attributes, because they carry meaning and may be associated to each other. Conceptual modeling may begin with concepts and associations only, as shown in Section 3.6, that is, attributes are not needed right away. However, when examined in detail, a concept usually contains a coherent group of attributes.

6.3.1 Unique attributes

It is assumed that different instances of a concept are distinguishable from each other just by the fact that they were created independently. This is not the case with primitive types. Two dates, such as 05/03/2013 and 05/03/2013, are the same. But two customers named John Smith are not necessarily the same person. Some programming languages indeed use two comparison predicates, one to check if two objects are equal (they have the same values for their attributes) and another to check if they are identical (they share the same space in memory).

Different instances are therefore always distinguishable from each other, but additionally they may have attributes that are unique to them. Once an attribute has been stereotyped as entuniqueent two instances of the concept cannot have the same value for that attribute. One example of a unique attribute is the ISBN for books, which is unique for each book (Figure 6.8), while the other attributes may have identical values for different books.

image

FIGURE 6.8 Class showing an attribute stereotyped as entuniqueent.

Unique attributes must not be confused with primary keys, entpkent. Primary keys are used especially for database design to provide a unique identification for an instance. But entuniqueent and entpkent are not identical, because a concept may have only one primary key, but more than one unique attribute. Unique attributes are closer to the idea of candidate keys in relational databases (Date, 1982).

6.3.2 System control class

Usually, the conceptual model is expected to be a connected graph, that is, every concept has a path (a sequence of associations) connecting it to every other concept. When that is not the case, it is supposed that something is missing, that is, important associations or concepts have not been discovered yet.

Although some authors oppose it, a concept that represents the system as a whole (in our example Livir) may be useful in the conceptual model if some precautions are taken. First of all, that concept should be declared as a Singleton;5 and second, it should not have attributes, being just a control class. This class corresponds to the system controller or façade-controller already mentioned in Chapter 5. It does not represent any data; it serves only as a point of reference to add associations to other classes, as seen in the following sections.

All concepts are associated directly or indirectly to the controller class in order to be accessible by the application.

The system controller class may be stereotyped with entcontrolent or drawn using Jacobson’s (1994) icon, as shown in Figure 6.9.

image

FIGURE 6.9 A system controller class.

In Chapter 9, the advantages of using the controller class are explained in detail. There are some situations that are nicely modeled as associations from the control class.6

6.4 Associations

When complex concepts are related, it is said that there is an association among them. Associations usually happen only between two concepts, but they can also be defined among three or more concepts. There may also be reflexive associations between instances of the same class. For example, the association that links parents to children is defined as a reflexive association from Person to Person.

When classes are associated, then their instances may be linked. For example, an order is linked to the books being ordered, and also to the customer that creates the order. A payment, if it exists, is linked to an order in the bookstore example.

Associations may be tricky to identify in use case texts, especially because sometimes deciding if something is a concept or association may be fuzzy. For example, is a book reservation an association between a book and a customer? Or is it a concept? If it is considered a concept, what are its own associations?

Moreover, use case texts often mention operations that are not exactly static associations. Operations such as buying books, or making a reservation, are dynamic transformations on data. They could produce concepts to represent their existence, but usually representing them as associations would not be adequate. It is necessary to take into account the difference between the (static) associations and (dynamic) operations:

• An association is a static relation that may exist between complex concepts, complementing the information about them in a given moment (a snapshot of their state), or referring to new associative information (for example, neighborhood or parent/children).

• An operation is the act of accessing and transforming existing information.

As a description of a dynamic process, a use case text is usually full of explicit references to operations, but associations usually have to be inferred from the text.

At a used car dealer there are people who buy cars from other people. When someone buys a car she is performing an operation. That operation changes the links between objects: one ownership link ceases to exist, while another is created in its place. It would not be appropriate to represent an operation as an association, as shown in Figure 6.10.

image

FIGURE 6.10 An operation inadequately labeled as an association.

Why is that interpretation not adequate? Because to buy is not a state of the information, it is a transition between states.

The state of the information about cars and people in this case is the ownership: a given person owns a car or not. This can be represented as an association between Person and Car (Figure 6.11).

image

FIGURE 6.11 Representation of a static association between two concepts.

However, there are different ways people and cars may be associated besides ownership. A person may be passenger of a car, or its driver, or the association may represent merely that someone likes a given car. To eliminate such ambiguities, it is convenient in many cases to use a role name on one or both association ends in order to indicate which role a class plays. Role names are not assigned to the association as a whole, but to both of its sides. Thus, a binary association has two role names: one for each participating class. In Figure 6.12, for example, a person is in the role of owner related to a car and a car belongs to the role fleet of a person.

image

FIGURE 6.12 An association with role names.

Different roles may be represented by different associations, as shown in Figure 6.13.

image

FIGURE 6.13 Multiple associations between the same concepts.

When an explicit role name is missing in the diagram, it is assumed that the class name (not capitalized) is the default role name. In the case of Figure 6.13, a car has two roles related to people: owner and driver. From the point of view of a person, there are two roles for cars: the fleet, which corresponds to the cars a given person owns, and a default role name car, which corresponds to the car a person drives.

According to the UML specification, associations can also have names (Figure 6.11 presents an example), which are placed in the middle of the edge that links the classes. However, such names, besides being difficult to give (novice analysts use to fill their diagrams with lots of associations labeled with “has” or synonyms), do not have much practical use.

It may be easier and more useful to work with role names instead of association names. In practice, one can ignore the fact that associations may have a name. Conceptual models can be perfectly clear with role names replacing association names. Role names are easier to give because they define navigation possibilities between concepts and are useful also for naming derived programming code elements such as the variables that would represent the association when the code is generated. If by any means an association name is still needed it is always possible to create it by composing the role names; the reverse is not true. For example, an association between a book and a customer could be called book2customer if it indeed needs to have a name (for example, for reference purposes).

Sometimes, it may be interesting to keep information about operations or transactions that were performed. For example, it would be useful for the car sales system to store information about sales transactions, as for example, date, value, etc. In this case, the information about the transaction is represented in the diagram, as a complex concept (Figure 6.14), and it represents statically the operation that was performed.

image

FIGURE 6.14 A transaction represented as a concept.

In this case, the transaction is represented as a concept, while its associations represent static relations between concepts.

6.4.1 Role multiplicity

In a conceptual model, it is fundamental to know how many elements a role accepts. For example, in the association between Person and Car with role name driver in Figure 6.13, how many cars can someone drive? How many drivers can a car have?

The answer depends on a study of the nature of the problem and on the real meaning of the association, especially if it represents the present time or the past. For example, if the association of Figure 6.13represents the present, then the car may have just one driver (one at a time). But if the association represents the past, then it is possible that a car has had a number of drivers who drove it during different periods of time.

Thus, it is fundamental that the team decides clearly what the association means before deciding on its role multiplicity. They have to remember that associations are static constraints; they represent whatever can exist between the instances of the associated classes. Therefore, depending on the meaning of the association, it may have different role multiplicities.

There are, basically, two decisions to be made about the multiplicity of an association role:

1. Is the role mandatory or not? For example, should a person have at least one car? Should a car have at least one driver or owner?

2. Does the number of instances that may be linked through the role have a defined conceptual bound? For example, is there a maximum number or minimum number of cars that a person may drive or own?

The answers to these questions may be tricky. Regarding the first decision, for example, returning to the Livir project, it is expected that each order must have a payment. But that does not qualify the payment role for an order as mandatory, because an order can exist without a payment for a period of time. Eventually, any order will hopefully be paid for, but not necessarily soon. Thus, this role is not mandatory for the order.

The other tricky issue concerns the maximum number of elements a role allows. Physically speaking, the maximum number of cars that a person may own is the number of cars that exist on planet Earth (the number is increasing, but it is defined at a given moment of time, even if it is hard to count). But as new cars are built, they may be purchased. Thus, although there is a physical limit for the ownership role, there is no conceptual or logical limit. Thus, the role should be considered virtually without upper bound.

Role multiplicity in UML is represented by a numeric expression where

• The asterisk “*” means “any quantity,” and indicates that there is no upper bound.

• The comma “,” means “or.”

• Two dots “..” means “up to.”

The following are examples of the usual multiplicity limits for conceptual models:

1 – exactly one

0..1 – zero or one

* – zero or more

1..* – one or more

2..5 – two up to five

2,5 – two or five

2,5..8 – two or from five up to eight

The multiplicity limits that include zero represent roles that are optional for a concept. All the other limits are mandatory.

Figure 6.15 shows an example where one person may have a fleet with an undetermined number of cars (optional), and a person may be a driver of one car at most (also optional). On the other hand, it shows that a car must have a single owner (mandatory) and that it may have a driver or not (optional).

image

FIGURE 6.15 Example of associations with role multiplicity.

According to many countries’ laws, a car may have more than one owner, or it may be owned by a corporation; in some situations a car may also have no owner at all. The conceptual model (such as the one in Figure 6.15) represents not necessarily a general truth, but the information needs for a given application. For some information systems it could be mandatory that a car, in order to be registered, have a single owner and that this owner must be a person. In this case, the conceptual model should represent the specific and pragmatic information needs for that system.

6.4.2 Association direction

An association in a conceptual model should be nondirectional, that is, the navigability of the association should not yet be determined (Booch et al., 2007). This is due to the fact that for analysis purposes, it is only necessary to know whether two concepts are associated or not; dynamic design will decide on navigability later.

There is, usually, little benefit to a premature (before dynamic design) definition of navigability direction. Unidirectional associations in general have the following advantages over bidirectional ones:

• It is not necessary to define a role name for both sides (just one).

• They are easier to implement.

Only the first advantage has any meaning for conceptual modeling, but it is too weak to justify making decisions prematurely.

6.4.3 Derived association

Just as useful as derived attributes are derived associations, that is, associations that instead of being represented physically are calculated from available information. For example, suppose it is often necessary to know which books a given customer has already bought in the Livir system. As books are not linked directly to the customer in the conceptual model, referring to that information could be a bit more complicated than expected. Figure 6.16 shows an example of how a conceptual model for Livir could relate books and customers indirectly through orders and purchasing items; in this case, the set of all books bought by a customer would be referred as the set of books linked to the items linked to the orders linked to the customer.

image

FIGURE 6.16 A customer indirectly associated to books.

Compared to the preliminary conceptual model of Chapter 3, Figure 6.16 introduces the concept Item between Book and Order. Items are necessary if the concept Book means the published title, not the physical copy. In this case, what is ordered is an Item, which represents one or more physical copies of a given Book. The book may have its price updated regularly, but a change in the book price should not affect the price of former orders. Thus, the price of an item remains the same even if the price of the book was changed.

Note that with this model there is no direct link between the customer and the books she has already bought. Creating a new straight association between Customer and Book would not be a good solution because it would be redundant to the model, as the set of books may already be obtained indirectly. Furthermore, a new association between Customer and Book could associate any customer with any book, not only those that were already bought by the customer through her orders. This model allows the representation of inconsistent information, which would require some checking mechanism (for example allowing only books that were bought to be associated to the customer).

A modeling solution for that case, when it is relevant to have straight access to a collection of objects that can already be derived from existing information, is to use a derived association, as depicted in Figure 6.17.

image

FIGURE 6.17 A derived association.

UML allows derived associations to be navigated in both directions. It is assumed that both roles are derived. In the case of Figure 6.17 the opposite role Customer must also be considered derived, even if its default role name does not indicate this in the diagram.

The multiplicity of both roles of the derived association of Figure 6.17 is multiple because by navigating on the normal associations it can be seen that a customer may have ordered zero or more books, and that a book may have been ordered by zero or more customers. Usually, the multiplicity of a derived association is defined by the product of the multiplicities of the roles that must be navigated to reach the target concept. The following rules may be used to determine that multiplicity:

• The lower bound of the derived multiplicity is the product of the lower bounds of the roles in the navigation path.

• The upper bound of the derived multiplicity is the product of the upper bounds of the roles in the navigation path.

For example, if the multiplicities found in the path are 1..5, 2..* and 1, then the derived multiplicity is 2..*, because the lower bounds are 1, 2, and 1 (1 * 2 * 1=2), and the upper bounds are 5, infinite, and 1 (5 * infinite * 1=infinite).

However, if filters are applied to the definition of the derived association, the resulting multiplicity may be different. For example, if the derived association is defined so that it links a customer to the most expensive book she has already bought, then the derived multiplicity is 1, and not *.

As opposed to normal associations that allow links between individual objects to be added and removed, a derived association may only be consulted (similar to derived attributes, which are read only).

A derived association may be defined by an OCL expression as well. The example of Figure 6.17 may be defined as

Context Customer::orderedBook

derive:

self.order.item.book

The following observations can be made about this OCL expression:

• The context is the class at the origin of the derived association (Customer). The subcontext is the role name of the derived association (orderedBook).

• The clause derive: is used similarly to the case of derived attributes. What determines if the expression is defining a derived attribute or association is the context and the type of information that is returned by the expression. Derived attributes are defined by expressions that return an alphanumeric, enumeration, or primitive type, while derived associations are defined by expressions that return an object or a collection of objects (data structure).

In object-oriented programming languages, usually the “.” notation can be used only over a single object. OCL, however, allows it to be used over collections of objects.7 If x is a collection, then the meaning of x.y is the collection of y that can be obtained as properties of x. For example, self.order denotes the set of orders of a customer in the current example; self.order.item is the set of items linked to the orders of a given customer; and self.order.item.book is the set of all books linked to the items that are linked to the orders that are linked to the customer.

A derived association may also be used to define a subset of objects from a set of linked objects by the application of a filter. For example, imagine that the bookstore has a record on special clients that have bought above 1000 dollars worth of books. Let us call them gold customers. Let us also assume that the Customer class has a derived attribute totalSales with the sum of all orders of a customer. The definition of that derived attribute is not important for the example and it will be ignored now. A derived association between the controller and the Customer class may be used to model the gold customers as a subset of the customers of Livir. Figure 6.18 shows the partial conceptual model for this example.

image

FIGURE 6.18 Derived association defining a subset of a normal association.

The OCL expression for this derived association has as the context the Livir controller itself, because it is at the origin of the association. The expression that defines the derived association has to denote the set of customers that bought more than 1000 dollars, that is, the instances of Customer whose totalSales value is higher than 1000.

The OCL expression to obtain a subset of elements that satisfy a given Boolean expression like this is select. The Boolean expression is placed inside parentheses after the select command. The Boolean expression usually starts with an iteration variable that in the case of the following expression was named: aCustomer.

Context Livir::goldCustomer

derive:

self.customer->select(aCustomer|aCustomer.totalSales>1000)

In the case of this expression, the iteration variable is called “aCustomer” but it could have any other name. It denotes each one of the customers for the evaluation of the expression aCustomer.totalSales>1000.

The arrow notation “->” is used before select instead of the “.” notation because the select function is applied over the structure of the set, not over its elements.8

OCL also allows the iteration variable to be omitted if the context of the expression is not ambiguous. Thus, the expression above can be simplified to

Context Livir:goldCustomer

derive:

customer->select(totalSales>1000)

Observe that inside the parentheses after select the context is potentially ambiguous. There, the property totalSales could refer both to a customer and to the instance of Livir. What allows us to eliminate the ambiguity is the fact that the property totalSales exists only in the Customer class; it does not exist in the Livir class. If it existed in both classes, then the nonabbreviated notation should be used in order to eliminate the ambiguous expression.

6.4.4 Aggregation and composition

Some associations may be considered stronger than others in the sense that they define one kind of object that is composed of others. A house, for example, is composed of rooms, a book of chapters, an undergraduate career of courses, etc.

If the association is exclusive, in the sense that an object may not be part of another object at the same time, then it is considered a strong part-whole association, which is called a composite aggregation,9 and it is drawn with a black diamond on the role that represents the whole (Figure 6.19).

image

FIGURE 6.19 An example of composite aggregation.

The multiplicity of the role that represents the composite (the side where the diamond is), in the case of a composite aggregation, should be 1 or 0..1, and nothing else, because composites do not share parts, even with objects of the same class.

Composite aggregation indicates exclusivity in the part-whole association. When this exclusivity is not mandatory (the part may be part of other aggregates), then a white diamond is used instead, and the association is called a shared aggregation (Figure 6.20).

image

FIGURE 6.20 An example of shared aggregation.

The white diamond indicates a shared aggregation where the part may belong to different wholes at the same time. In Figure 6.20, a given Item must be part of an Order, but also may be part of a Sale.

Composite and shared aggregation are special associations and should be used with much parsimony, that is, they should be used only when the team is sure that it is the case that an object is really part of another, and not just a normal association. Even the UML specification (Object Management Group, 2011) states that the precise semantics of a shared aggregation varies between application areas and modelers.

It is common to see aggregation and composition being abused in models, when objects that are not part-whole related are linked by that kind of association. For example, a customer is not part of an order, if not for any other reason but the fact that a customer is a person and an order is not a physical thing, but a transaction. Composite and shared aggregations should unite elements of the same nature: physical with physical, and abstract with abstract. An order may be associated to a customer, but the order is not made of customers.

There are few real advantages in using aggregation in conceptual modeling. This is another reason to minimize or even abolish their use in conceptual models. Among the advantages is that composite or shared aggregation parts usually have attributes that are combined and derived in the whole. For example, the total value of an order is the sum of its items; the weight of a package is the sum of the weight of each book; when a car is sold, all its parts are sold too; and so on. However, these concerns usually appear only at design time.

6.4.5 n-ary associations

Most associations are binary, that is, most associations have only two roles. However, there are situations where associations with three or more roles are needed. In UML, these associations can be represented by using a diamond that connects all the roles of the association, as in Figure 6.21.

image

FIGURE 6.21 An example of a ternary association.

The example in Figure 6.21 was taken from a budget control application. Each project may be associated to multiple budget items and multiple financial years. Each financial year may have a number of budget items per project. A ternary association (that is, an association with three roles) represents this situation, as seen in Figure 6.21.

These cases are not frequent, but they may appear in a project. Before deciding to use a ternary or n-ary association (which may be a headache during design and implementation), the team should verify if they are not confusing it with a situation where a combination of binary associations should be used instead. For example, the case shown in Figure 6.22 is not correctly modeled as a ternary association, because the relation between the author and the publisher happens only when the author publishes a book with a publisher. Then, the association between the author and the publisher would be a derived one.

image

FIGURE 6.22 An unsuitable ternary association.

The model represented in Figure 6.23 is more precise than the one in Figure 6.22 for the case being discussed. Only in a scenario where the same author could publish the same book using a different publisher and the publisher could publish the same book with a different author (!) would there be a case for a ternary association.

image

FIGURE 6.23 The model of Figure 6.22 correctly represented with two binary associations.

Real ternary associations, however, may still be replaced by a combination of binary ones. Maybe the simplest approach to accomplish this is to replace the ternary (or n-ary) association by a new concept. Sometimes, naming the new concept may be tricky, but it can be done. For example, the model of Figure 6.21 could be replaced by the one shown in Figure 6.24.

image

FIGURE 6.24 Model where a ternary association is replaced by a new concept.

However, there is a subtle semantic difference between the models in Figures 6.21 and 6.24. In the case of Figure 6.24, there may be two or more Spendable instances with exactly the same budget item, financial year, and project. This cannot happen in the case of Figure 6.21. Thus, for this simplification to have the same semantics as the ternary association, it is necessary to complement it with an invariant (see Section 6.7).

6.5 Collections

Simple collections of objects that do not have any particular meaning or structure should not be, in principle, represented as concepts, but as associations. Any association role already represents a collection of objects of the associated class. Thus, considering again the example of Figure 6.15, fleet is a role that associates a set of cars to a person. The model presented in Figure 6.25 is, therefore, unnecessary and redundant.

image

FIGURE 6.25 A simple collection being inadequately represented as a class.

Thus, unless the fleet has its own attributes or associations (for example a person having multiple fleets located in different places) the correct form to represent a simple collection of objects is through an association role, not through a class (Figure 6.26).

image

FIGURE 6.26 A simpler model for the situation presented in Figure 6.25.

Thus, the team must be aware that if the collection has particular attributes or associations, then it must be represented as a concept. For example, an Order is initially understood as a set of items, but an Orderalso has attributes such as issue date, total value, discount, etc., and associations such as the one with the customer, who may have multiple orders. If that is the case, the collection is a concept. However, a collection with no particular attributes or associations is just a collection, and therefore it is modeled as an association role.

Association roles may be thought as representing abstract data types (Liskov, 1974) in conceptual models. In design models they would also represent concrete data types. Abstract data types are defined only by behavior, not by structure. They appear, for example, in the following:

• The set structure, in which elements do not repeat and have no defined position.

• The bag structure, in which elements may repeat but still do not have a defined position.

• The ordered set structure, in which elements do not repeat but have a defined position.

• The sequence structure, in which elements may repeat and have a defined position.

The concrete data types, on the other hand, are physical implementations for the abstract versions. For example, a list may be implemented in many forms, such as an array, binary tree, linked list, etc. In the case of concrete data types, besides behavior, there is also a physical structure that defines them.

6.5.1 Set

An association role, by default, is a set, that is, a structure where elements do not repeat and where there is no defined position for them. In Figure 6.26, the fleet is an example of a set.

If someone tries to link the same car to the same person a second time, nothing happens, because it already belongs to the set.

6.5.2 Ordered set

Suppose a book that is not yet in stock has a list of people interested in buying it as soon as it is available. If it cannot be assured that the quantity of books received will fill all the orders, then the fairer way to attend to these customers is by establishing a line from the oldest reservation to the newest. This requires that the customers have a position in the line.

If the same customer cannot reserve the same book more than once, then it is still a structure with no elements repeated, but now with defined positions. This leads to the ordered set structure. In the diagram, the role may be marked with the constraint {ordered} to indicate that it is a collection where elements do not repeat but have defined positions, as seen in Figure 6.27.

image

FIGURE 6.27 An ordered set of reservations for a book.

The constraint {ordered} over an association role means that the elements linked on that role have position (first, second, third, … , last), but still cannot be repeated.

6.5.3 Bag

There are situations in which the position of the elements does not matter, but each element may appear more than once in the collection. That structure is called a bag.

For example, one may need to know how many people viewed the details of a book, and it may be important also to know how many times each one viewed it. It is not necessary to know who viewed it first, but the information on the number of views is necessary. That is a typical case for using a bag. Each time a person views the details of a book, a new link is added on the association defined as a bag. The model is shown in Figure 6.28.

image

FIGURE 6.28 An example of a bag.

6.5.4 Sequence

The sequence allows elements to be repeated and also assigns a position to them. For example, imagine that people that buy a given value worth of books qualify for receiving a gift, but a limited quantity of gifts is available. Thus, a list of people that qualify to receive the gift may be built and the gifts will be distributed to the first members of the list as soon as gifts become available. If someone again buys more than the limit established to receive a gift, she will enter the list again. Thus, in that structure the position of an element is relevant and each element may appear more than once: this corresponds to a sequence structure, as seen in Figure 6.29.

image

FIGURE 6.29 An example of a sequence.

The multiplicity * on the Livir side means that not all customers are qualified for a gift and that they may qualify more than once.

The sequence has two important special cases. When the first element to be removed is always the oldest in the sequence, as in the case of Figure 6.29, then the structure is also a queue. UML does not define a constraint for queues, but a stereotype on the sequence constraint would do the job: {sequence} entqueueent.

When the first element to be removed is the newest in the sequence, than it behaves like a stack, and may be stereotyped as such: {sequence} entstackent. Queues and stacks that do not repeat elements may be defined respectively as {ordered} entqueueent and {ordered} entstackent.

A general list may have elements removed and inserted at any position. Queues and stacks have elements inserted and removed only at predetermined positions, as explained above, although, in some cases, all of their elements may be browsed.

A curiosity to be mentioned now is that in the real world most collections are strict sets and not sequences, but even so, the most used programming structure is still the sequence, and not the set, which indicates a gap between reality and the data structures used in programming.

6.5.5 Map

When a concept has a unique attribute, a map may be created from that attribute to the concept, in such a way that it is easier to identify and find specific instances of the concept. For example, as the ISBN is unique for a book, associations to Book may be qualified by the ISBN, meaning that instead of having a set of books, the origin class has access to a map that allows immediate identification of any book if its ISBN is known. Figure 6.30 shows an example of qualified association.

image

FIGURE 6.30 An example of qualified association representing a map.

The small rectangle at the left side of the association in Figure 6.30 represents a qualifier for the class at the opposite side of the association. Notice that instead of “*,” the role of the right side is now bounded by “0..1”; the association should now be read as follows: “for each possible ISBN there is no more than one book.” Some valid ISBN values may not be associated to any book, because they were not registered in the system or because the ISBN, although valid, has simply not yet been assigned to a book; however, if one ISBN is taken by a book, no other book may share it. In practice, a qualified association is still an association “to many,” but the objects belonging to the role may be accessed by one of their attributes.

The role at the left side (the qualifier side) is marked with “1,” meaning that each book has a single ISBN, not less or more. This has to necessarily be true, because an ISBN is unique and not optional for the class Book, and therefore, it is mandatory and does not allow repetition.

The qualifier is not only a way to access objects in an easier way. It is also a powerful modeling tool. For example, consider a situation where a person may own many phones, but only one of each kind. How do we represent this? An elegant model for that situation is shown in Figure 6.31.

image

FIGURE 6.31 Use of a qualifier as a modeling tool.

In the case of Figure 6.31 one person may have up to four phones, but just one of each kind. If more kinds are added to the enumeration later, then more phones may be associated to each person. If the role on the right side was 1 instead of 0..1, then one person should necessarily have four phones, each one a different kind. That use of a qualified association with a mandatory role usually makes sense only when the qualifier is an enumeration or a finite set.

In the example of Figure 6.30, the qualifier is an attribute of the qualified class, and in that case it is called an internal qualifier. On the other hand, in Figure 6.31 the qualifier is not an attribute of the class, and it is called an external qualifier.

6.5.6 Partition

In Figures 6.30 and 6.31, the multiplicity 1 or 0..1 on the right side of the figure means that the association is a mapping, that is, for each value of the key there is at most one instance of the qualified class.

What if instead of “1” or “0..1” the multiplicity was marked with “*”? In this case, the association would read as follows: “for each key there is a set of instances of the qualified class.”

For example, books may be classified by genre. As many books may belong to the same genre, the genre attribute may not be unique. But it is possible to define a partition on the set of books based on their genre, as shown in Figure 6.32.

image

FIGURE 6.32 An example of a partition.

Figure 6.32 states that for each particular value of genre there is a set of books (with zero or more elements). The role multiplicity 1 on the left side indicates that every book has a genre.

6.5.7 Relation

Now, imagine that a book may have more than one genre, as, for example, The Hitchhiker’s Guide to the Galaxy (Adams, 1979), which can be classified both as science fiction and humor. For representing the possibility of a book having more than one genre in the example of Figure 6.32, it would be sufficient to change the multiplicity on the left side of the association to * (if a genre is optional) or 1..* (if it is mandatory). Additionally, the genre should be removed from the attributes of Book, becoming an external qualifier, because the genre attribute should allow multiple values. Figure 6.33 shows the resulting relation.

image

FIGURE 6.33 An example of a relation.

The relation of Figure 6.33 states that a book may have one or more genres and a genre has a set of books associated with it. As a book may have more than one genre, then the qualifier should be necessarily external.

6.6 Organization of the conceptual model

The elaboration of the conceptual model involves more than just putting concepts, attributes, and associations together. For the conceptual model to be a reliable and organized representation of real-world information, it is necessary to use some modeling techniques.

The main organizational techniques for concepts may be distinguished into three groups:

Structural: Representing generalizations among concepts, as for example, BankAccount generalizing SavingsAccount and CheckAccount.

Associative: Representing associative roles that some concepts may play related to others, as for example, Student and Professor being roles a Person may play related to a school.

Temporal: Representing relations among different states of a concept, as for example an Order being in states AttendingPayment and Paid.

Novice analysts and sometimes even experienced ones tend to think that the only way to factorize information is by the use of inheritance, or generalization.10 However, it is necessary to apply some judgment before deciding on using this or that technique. Inheritance may be used only when a concept effectively has two or more subtypes. Although UML allows an instance to change its class, only a few languages, such as Smalltalk (Goldberg & Robson, 1989), tried to implement such a feature, maybe because there are some unresolved inherent difficulties associated to the fact that one instance could change its internal structure on the fly. Most object-oriented languages ignore this feature due to the problems it raises and due to the fact that it is usually unnecessary, because most behaviors that could be modeled by this feature also have alternate simpler representations. Thus, for practical terms, it is usually the case that an instance may not change its class: it is born as a member of one class and it will die a member of the same class.11 As students may become professors, they do not qualify as subtypes of people (the best solution for modeling this situation is given in Section 6.6.2).

Another counterexample is Worker and Customer being modeled as subclasses of Person. This is bad first because no one is born a worker or customer; a person becomes a worker or customer when associated to a company. More than that, the same person may be a customer or worker in more than one company. Using inheritance in this case would create conceptual problems that can produce duplicity in records and data inconsistency.

The following subsections present details on the three approaches to the organization of concepts.

6.6.1 Generalization, specialization, and inheritance

For years, inheritance was considered the most important feature of object-oriented languages. Languages such as Smalltalk, for example, were built over a single hierarchy of classes based on inheritance.

As time went by, this emphasis lost strength, because it was perceived that inheritance is not always the best idea for solving modeling problems. Today, inheritance is considered just one of the techniques that help to factorize information that otherwise would be repeated in classes.

Inheritance, in object-oriented systems, occurs when two classes relate through a special association called a generalization (or a specialization, depending on the direction you look). A class that generalizes another class is its superclass, and the specialized one is the subclass.

Generalization should be used every time there is a set of classes X1, …, Xn that have specific differences and common similarities, so that the similarities can be grouped in a superclass X (generalization of X1, …, Xn) and the differences maintained in X1, …, Xn.

The generalization has a semantic much different from the other associations of the conceptual model. It exists only between classes, not between instances as normal associations do. For example, if a class Customer is associated to the class Order by a normal association, then instances of Customer may be linked to instances of Order: the normal association allows the links to exist. On the other hand if a class BankAccount is a generalization of CheckAccount, then every instance of CheckAccount is also an instance of BankAccount (Figure 6.34). There are not two instances to be linked, just one instance with the properties defined in both class. In the example, every instance of CheckAccount has three attributes: number, overdraftLimit, and overdraftFee. However, not every instance of BankAccount is an instance of CheckAccount: the generalization is anti-symmetric. An instance of BankAccount has only one attribute: number.

image

FIGURE 6.34 An example of generalization with inheritance.

Thus, one of the reasons to use inheritance is when there are some similar properties (attributes, associations, or methods) in different classes, which may be factorized in an abstract construct such as a superclass.

If the superclass may have its own instances, then it is a normal class. However, most of the time superclasses are defined not to allow direct instances: only their subclasses may have instances. In this case they are known as abstract superclasses. Abstract superclasses are represented in UML by a class with its name written in italic, or, more visibly, with the constraint {abstract} (Figure 6.35).

image

FIGURE 6.35 Two classes being generalized by an abstract class.

In Figure 6.35, the BankAccount class is abstract, and therefore cannot have direct instances; only its subclasses may have instances. Instances of CheckAccount have number, overdraftLimit, and overdraftFee as attributes; instances of SavingsAccount have number and interestRate as attributes. Both subclasses also inherit the association to the class Customer, and all instances of both classes must, therefore, be linked to an instance of Customer.

Generalization in not advisable when the superclass has no properties, that is, no attributes, associations, or methods of its own (Figure 6.36).

image

FIGURE 6.36 Situation where generalization is not recommended, because there are no generalized properties.

Generalization should also not be used when subclasses do not have properties (attributes, associations, or methods12) that differentiate them from each other as in Figure 6.37.

image

FIGURE 6.37 Situation where specialization is not recommended because there are no properties being specialized in subclasses.

In these cases, the ideal solution is to use a single attribute, possibly typed with an enumeration, to differentiate instance groups of objects that have the same properties (Figure 6.38).

image

FIGURE 6.38 A more adequate model for the situation of Figure 6.37.

Besides these rules, before deciding on the use of inheritance, it is advisable to verify if the generalization really represents a structural classification of the elements, and not an associative or temporal organization, as seen in the following sections.

6.6.2 Association classes

One issue frequently misunderstood in conceptual modeling is related to the definition of generalization among classes that are not really structural subtypes, but roles. For example, a bookstore may have two “types” of people: customers and workers. After discovering that both have a name, address, phone, etc., an analyst could assume that they are two concepts that should be generalized as Person. But that apparently simple solution (Figure 6.39) generates a complicated problem, because they are not different types of people, but different roles that people could play when relating to a company.

image

FIGURE 6.39 Unsuitable way to represent roles with generalization.

Why is this a problem? Imagine that a bookstore worker decides to buy books at her workplace. In this case the worker will be behaving like a customer. An unsuitable although very frequent solution to this is to create a second record for the worker as a customer, as if she was a different person. As a consequence, the same person would have two records in the system: one as a worker and another as a customer. This produces data redundancy and it is a source of data inconsistency, because, for example, if the worker has registered a change in address, the customer may still keep the old address. As they are the same person, this information is inconsistent.

A more suitable solution is to consider that there exists a Person that may relate to a Company in at least two ways: as a customer and as a worker. The specific properties of a customer (credit limit, for instance), and of a worker (salary, for instance), would be properties of the associations, and not of the person. To represent these association properties, an association class should be defined for each one, as shown in Figure 6.40.

image

FIGURE 6.40 More suitable representation of roles as class associations.

Therefore, when the same object may play different roles related to other objects, these roles should not be represented as subclasses, but as association classes.

In order to decide which situation demands inheritance and which situation demands association classes, it may be verified if the “subtypes” depend on the existence of a third class to make sense. If the “subtype” depends on a third class, then the solution consists of using an association class. For example, nobody may be simply a student; if someone is a student, then she must be associated to a school or at least to a teacher.

Thus, it is unsuitable to create classes that represent kinds of people that in reality are not subclasses, but roles. Workers, teachers, students, principals, customers, etc., should not be subclasses of Person. Concepts like these only make sense if related to other concepts such as Company, School, Department, etc. A person may be worker at a company, student at a school, etc.

The difference between using an association class and an intermediary concept is subtle. Figure 6.41 shows an example of a reservation being modeled as an intermediary concept, and Figure 6.42 is a version of that reservation modeled as an association class.

image

FIGURE 6.41 A reservation being modeled as an intermediary concept.

image

FIGURE 6.42 A reservation being modeled as an association class.

In the case of Figure 6.41, a reservation associates a customer to a book. In the case of Figure 6.42 the customer and the book are directly associated, and the reservation, as an association class, is a consequence of that association. However, in Figure 6.41, the same customer may have many reservations for the same book (nothing in the model prevents it), while in Figure 6.42 one customer may have just one reservation for each book. The link between the customer and the book may exist or not; it is not a bag. However, if both roles of the association in Figure 6.42 were marked with {bag}, then a user could have more than one reservation for the same book and the model in Figure 6.42 would be equivalent to the one in Figure 6.41.

The issue of having different records for the same person, as discussed above, frequently creates problems in information systems. For example, a student enters the university and is registered as such. Then, she receives a scholarship and a new record is created. Then, she works at a lab, and is registered again. Finally, she is hired as a professor and a new record is created. She appears many times in the university records, as if she was different people. Her old records become out of date; address and phone numbers usually are only updated in the most recent records. This happens because systems usually use inheritance (Figure 6.43), or completely separated records (Figure 6.44) in these cases.

image

FIGURE 6.43 Unsuitable representation of many records for the same person with inheritance.

image

FIGURE 6.44 Unsuitable representation of many records for the same person as separated concepts.

To avoid this problem, as seen before, the solution is to recognize that a person is always the same. The person’s roles at the institution change, but the person does not become a new person. Thus, the solution for this situation is more suitable when based on association classes, as shown in Figure 6.45.

image

FIGURE 6.45 Representation of many records for the same person as association classes.

In Figure 6.45, if a person can play the same role more than once, then the multiplicity at the left side of the association should be *.

A reasonable exception may be admitted if just one kind of person exists in the context of the system. For example, if the system only manages information about professors and that is the only role a person may play at the university in the context of that information system, then it would be easier just to create a class named Professor, and in the context of that system, Professor is a synonym of Person because there are no other kinds of people. The same thing happens in the Livir example, where it was decided to keep Customer as the only class representing people, instead of transforming it into an association class.

6.6.3 Modal classes

Modal classes are used to model concepts with instances that can change from one state to another during their existence, changing, possibly, their properties’ structure, including attributes, associations, and behavior. Although a few programming languages allow instances to change their structure by changing their class, this is not assumed as a modeling principle because such changes may create unpredictable structural problems.

Even if an instance could change its class, redefining its attributes and associations remains a problem. However, there are modeling techniques that allow one to represent situations that would need objects that change class without using this feature. The idea is not to change the object class, but its state. When a TV is turned on it does not become a new type of TV: it just changes its state.

Three increasingly complex situations related to state modeling may be identified:

Stable transition: The different states of an object do not affect its structure, but only its property values (attributes and links).

Monotonic increasing transition: As the object changes state it may only keep its properties or acquire new ones.

Nonmonotonic transition:13 As the object changes state it may keep, acquire, or lose properties.

Modeling solutions for the stable and monotonic increasing transitions are quite simple. However, for modeling the nonmonotonic transition, a design pattern named State (Gamma, Helm, Johnson, & Vlissides, 1995) is necessary, as seen in the following subsections.

6.6.3.1 Stable transition

Frequently, different states of an object may be represented by a simple attribute. In fact, the set of all attributes and links of an object defines its state. For example, the state of an order could be modeled simply as a state attribute typed with an enumeration whose values may be “ongoing,” “concluded,” and “paid.”.

Another example is the suspended attribute of the Address class (Figure 6.46). If a package sent to that address returns, then the address is marked as suspended (the attribute is changed to true). When the customer updates the address it is changed to false again. The default value for the suspended attribute is false.

image

FIGURE 6.46 A concept with a stable state transition.

If the attribute suspended is true, then the address cannot be used for deliveries.

The transition is considered stable because just the value of the attribute changes. The inner structure of the object is kept the same. This does not happen with the two cases presented in the next subsections.

6.6.3.2 Monotonic increasing transition

The situation is a bit more complex when the concept may acquire new attributes or associations as it changes state. For example, invoices that are waiting for payment have only dueDate and dueValue as attributes. But an invoice that is paid additionally has paymentDate and paidValue (Figure 6.47).

image

FIGURE 6.47 A concept with a monotonic increasing transition.

It is said that the transition in Figure 6.47 is monotonic increasing because new attributes and associations may be created for it, but not eliminated. This implies that a paid invoice cannot go back to be a new invoice again.

It would not be adequate to model that situation with inheritance, as seen in Figure 6.48, because in that case, an instance of NewInvoice should be transformed into an instance of PaidInvoice, or it has to be destroyed and created again from scratch, and all its references should be rebuilt.

image

FIGURE 6.48 Unsuitable way to model a monotonic increasing transition with inheritance.

Another solution that is not very nice, but still very popular, consists of creating a single class Invoice and allowing certain attributes to be null until the class changes its state, as shown in Figure 6.49. Usually, the verification of the instance consistency is done in the updating methods. But an invariant could also be used (as explained in Section 6.7) to guarantee that no instance reaches an invalid state, as, for example, with a defined paymentDate and null paidValue.

image

FIGURE 6.49 Unsuitable way to model a monotonic increasing transition with a single class and null attributes.

This model is still not good because it generates a class with low cohesion, which has, in consequence, complex consistency rules that should be checked frequently. This kind of class is highly susceptible to design and programming errors.

It would be better to model the invoice concept so that the consistency of the objects could be constrained by the structure of the model itself, and not by external rules. As it is a monotonic increasing transition, then it is possible to model this situation just by splitting the original concept in two: one that represents the invoice, and another that represents its payment with the properties that were added when the payment occurred. These two concepts are, then, linked by a 1 to 0..1 association (Figure 6.50).

image

FIGURE 6.50 Effective way to model a monotonic increasing transition.

With the model presented in Figure 6.50 it is impossible for an invoice to have a defined payment date and undefined paid value, and this is guaranteed without performing any further constraint on its attributes or associations.

The state of an invoice is a derived attribute, which is calculated as follows: if there is no payment linked to the invoice, then the invoice is new; otherwise it is paid. In OCL that condition may be expressed as

Context Invoice::state

derive:

if self.payment->isEmpty() then

InvoiceState::new

else

InvoiceState::paid

endif

The expression above introduces two new OCL features:

if-then-else-endif, which is one of the OCL selection functions. If the condition after the if is true, then the function results in the evaluation of the expression after the then; otherwise it results in the evaluation of the expression after the else.

isEmpty(), which is a function applied to a collection structure and returns true if the collection is empty or false otherwise. It is an easy way to check if there is some object linked to another object or not.

6.6.3.3 Nonmonotonic transition

With nonmonotonic transition, an object may both gain and lose properties as it changes its state.

Fortunately, it is not frequent that an information system requires any information to be lost. However, sometimes, that can be exactly what should be done.

There are many ways to conceive and model a reservation system for a hotel, for example. One of them consists of regarding the hosting as an entity that evolves from a reservation in three steps:

1. Initially, a potential guest makes a reservation indicating the days she intends to arrive and depart, the kind of accommodation, and the number of people. The hotel provides the fee.

2. When the guest checks in, the arrival date is registered (it may be the same date of the reservation or a different date). The hotel assigns a room that may be different from the one initially reserved and, if this is the case, it informs the guest of the new fee. The expected date of departure continues to exist, although it can be updated during the stay.

3. When the guest checks out, the expected departure date ceases to exist and the effective departure date is registered, and the bill has to be paid.

This set of states may be modeled during business analysis with a state machine diagram similar to the one in Figure 6.51.

image

FIGURE 6.51 A state machine diagram for modeling a simple hosting process.

If a hosting just acquires new attributes and associations as it evolves through the states of Figure 6.51, then it could be represented by a chain of concepts like the one shown in Figure 6.52.

image

FIGURE 6.52 Possible model for reservations as monotonic increasing transitions.

However, it is possible to assume that some state transitions may eliminate some attributes or associations that have no more meaning in the new state, as, for instance, estimated dates, which are replaced by real dates, and the type of room, which will be replaced by a real room that already has a type.

In order to represent this kind of situation, it is necessary to use a design pattern known as State (Gamma, Helm, Johnson, & Vlissides, 1995). According to this pattern, a class should be separated from its states. Properties that are shared by all states are kept in the original class, and properties that belong only to one or a few states are moved to the respective states. These states are specializations of an abstract class, as shown in Figure 6.53.

image

FIGURE 6.53 Nonmonotonic state transitions modeled with the State design pattern.

In Figure 6.53, the attributes nrPeople and fee exist in every possible state of a hosting, and this is why they are represented in the Hosting class. The other properties are distributed among the three possible states:

Reservation: A hosting, in addition to the number of people, has estimated arrival and leaving dates and the accommodation type (not yet a room), from which the initial value for the hosting fee is obtained.

CurrentLodging: A hosting, in addition to the number of people and fee, has an effective check-in date, estimated leaving date, and an effective room assigned. The estimatedArrival attribute and the straight link to the accommodation type are not necessary anymore and are discarded.

FinishedLodging: A hosting, in addition to the number of people and fee, has effective check-in and check-out dates, and an effective room that was assigned. The estimated leaving date is not necessary anymore and is discarded.

From the point of view of a Room, it can be linked to at most one CurrentLodging (0..1), but it can be associated to many FinishedLodging (*). This way, the temporal property of that association is already modeled too, because the association of a room to lodging may be at most one in the present, but many in the past.

6.7 Invariants

There are situations where the expressivity of the diagrams is not enough to represent rules that should be recorded in the conceptual model. In these cases, the analyst should use invariants.

Invariants are general constraints over instances of the classes. Some constraints are represented in the association roles; for example, a constraint that states that an order should have not more than five items can be represented as in Figure 6.54.

image

FIGURE 6.54 A constraint that can be represented as a role multiplicity.

However, not every possible constraint may be represented in the association roles. Consider the model shown in Figure 6.55.

image

FIGURE 6.55 An example of a class with an invariant.

The totalValue of an order is a derived value in Figure 6.55. The sum function in OCL returns the sum of the numerical elements that are produced for each of the elements of the set. The expression between parentheses after sum indicates how each individual numerical value is obtained from the elements of the set. The expression used to define the totalValue in Figure 6.55 is an abbreviation of

Context Order::totalValue:Money

derive:

self.item->sum(anItem|anItem.subtotal)

Someone could also try to write the expression above as self.item.subtotal->sum(aSubtotal|aSubtotal) or self.item.subtotal->sum(). However, in that case, as the role item is a set and not a bag or sequence, the subtotals would be also a set. If two items have the same value for the subtotal, then it would appear just once in the set and the sum would not reflect the intentions of the modeler.

The subtotal in the Item class is also a derived value calculated by the following expression:

Context Item::subtotal:Money

derive:

self.quantity*self.price

The item price has an initial value defined as the price of the book that is linked to the item:

Context Item::price:Money

init:

self.book.price

Now, if there is a constraint that states that no order can have a total value higher than 1000 dollars, it would not be possible to represent it in the role multiplicity, as done in Figure 6.54. However, the constraint could be represented by using an invariant like the following:

Context Order

inv:

self.totalValue<=1000

Invariants may appear in the diagram indicated as constraints associated to a class. The invariant mentioned above is represented just below the Order class name in Figure 6.55.

The invariant declaration in OCL does not have a subcontext; it must be true for every instance of the class, not for a particular attribute or association role.

Many software developers, when faced with the need to use constrains like invariants, choose to incorporate these rules in methods that update the attributes and links of the objects. For example, considering Figure 6.55, a test for the constraint could be added to the method that adds a new item to the order to check if the total value surpasses one thousand dollars; in that case, the operation would be prevented from completing.

The problem with that approach is that the verification would be made only on that method, but it would not be a general rule for every method. The developer knows the rule now, but what happens if another developer assumes the project later? What about maintenance? A developer that changes the system some years later would not necessarily know that that rule exists. She would probably not review the requirements document (assuming that it still exists and is updated), and she would potentially introduce a conceptual error in the system if she allows other methods to not follow that rule.

For instance, if the check was implemented only in the operation that adds a new item to an order, what if the item has its price changed? What if the item has its quantity changed?

Thus, general conceptual rules that always apply should be explicit in the conceptual model, and not relegated to verifications in the programming code. Inconsistent instances may be prevented. If it is possible, such constrains may be represented in the diagram structure; otherwise, they should be represented by invariants.

Another example, which happens frequently, is the need to constrain two associations that would be independent otherwise. In Figure 6.56, note that students are associated to a chosen career, each career has courses, and students take courses.

image

FIGURE 6.56 A model that needs a further constraint to be consistent.

However, the model depicted in the figure does not guarantee that students will choose courses associated to their career. According to the model, a student may take any course, and if that is not the case, a constraint should be added to the model. UML allows constraints to be added between associations (with the use of dashed lines). This notation is an alternate form for an invariant.

To guarantee that a student can only take courses related to her own career an invariant like the following should be provided:

Context Student

inv:

self.course.career=self.career

The expression uses a feature of sets (not allowing elements to be repeated) to verify that all courses taken by the student belong to the student’s career. The expression self.career results in the student’s career (a set with a single element because of the multiplicity of the role from student to career). On the other hand, the expression self.course.career results in the set of all careers associated to all courses taken by the student. If there are courses from different careers, then that set could not be equal to self.career (which has a single element). Otherwise, if all careers are the same then the set self.course.career will contain a single element (because sets do not repeat elements). If that element is the same as self.career, then the invariant will be true and valid.

6.8 Iterative construction of the conceptual model

This section shows how the conceptual model can be refined with information from the expanded use cases. Initially, we discuss how to find concepts and attributes from the use case texts. Next, we discuss how to identify associations of the model. Finally, we present a complete example with some use cases from the first iterations of the Livir project, and their contribution to the conceptual model.

6.8.1 How to find concepts and attributes

The process of discovering the elements of the conceptual model may vary. However, one of the most useful techniques is to look at the text of the expanded use cases or system sequence diagrams. From those artifacts one can discover all textual elements that eventually refer to information to be managed.

Usually, these textual elements are composed by nouns such as “person,” “order,” “payment,” etc., or by expressions that denote nouns (known in linguistics as noun phrases), such as “payment authorization.” Moreover, sometimes even verbs may represent concepts, when verbs express an act that corresponds to a noun, as, for example, the verb “paying,” which corresponds to the noun “payment.”

The analyst should mind the project goals and scope when looking for the elements of the conceptual model. It is not advisable to represent in the conceptual model information that is irrelevant to the system. Thus, not every noun, adjective, or verb should be considered as a model element. The analyst is responsible for understanding what the real information needs of the system are, and for filtering the irrelevancies.

The process of identification of concepts and attributes consists of the following:

1. Identify in the expanded use case text or in the arguments of the operations in the system sequence diagram the words or phrases that correspond to concepts that are relevant to maintain the record.

2. Group words or phrases that refer to the same entity as, for example, “buy” and “acquisition,” “customer” and “client,” etc.

3. Decide which of the identified elements are complex concepts, and which are mere attributes. Usually, attributes are the elements that may be considered alphanumeric (names, numbers, codes, monetary values, Boolean values, etc.), enumerations, or primitive (dates, ISBNs, etc.).

Applying this technique to the use case of Figure 5.10, the main elements related to the use case may be found. Figure 6.57 shows these elements underlined.

image

FIGURE 6.57 Use case with candidate concepts and attributes underlined.

Even if there is no preliminary conceptual model, this use case is enough to identify some concepts that belong to the system domain. If the preliminary conceptual model already exists, then the use case helps to refine the model, indicating new concepts, new attributes, or structure changes. For the example, we assume that there is already a preliminary conceptual model, which is depicted in Figure 6.58.

image

FIGURE 6.58 Preliminary conceptual model for the current example.

The terms identified in the use case text of Figure 6.57 are, in order of appearance:

Customer: A class that is already in the conceptual model.

Keyword: Keywords are used for searching; they are not considered at this point attributes of complex concepts on their own (although they could be if search history or preferences have to be recorded).

Book: A class that is already in the conceptual model.

Sale: In the context of that use case and at this point of analysis “sale” and “order” could be considered synonyms. Thus, this is a class that is already in the conceptual model.

Title, author, price, and page count: Attributes of Book. Author could still be considered a complex concept if the information about authors is more complex than a single name.

Publisher: A class that is already in the model. The use case probably is referring to the publisher’s name.

ISBN and cover image: Attributes of Book.

Desired quantity: Cannot be considered an attribute of Book because it varies depending on the order. It cannot be considered an attribute of the order either because it varies depending on the book (there may be many books in an order). The desired quantity is, therefore, an attribute of the association between a book and an order, represented by an intermediary concept or by an association class called Item.

Order summary: This is referring to an Order; it does not seem to be a new concept.

Title, author (or author’s name), quantity, unit price, and subtotal: Except for subtotal all attributes have been already mentioned. Subtotal may be a derived attribute of an Item. Unit price is equivalent to price, which is already considered an attribute of Book. However, it may in fact also be an attribute of Item as well.

Total value: Derived attribute of Order.

Finishes the order: This indicates an action that represents a change in the state of an order. Maybe an attribute would be sufficient to represent this state, but more analysis would be advisable in order to see if finishing an order is not a more complex operation (which is indeed it is).

Quantity requested: Same thing as quantity.

Quantity in stock: Probably a new attribute of Book.

Available quantities: Synonym of quantity in stock.

Identified: Could this be a state of a customer? Maybe not. It refers to whether the user is logged in or not.

Valid identification: This belongs to the security domain. However, the conceptual model probably may have a way to identify customers. Usually ID numbers such as the Social Security number are used for that purpose.

Account: This again has to do with login.

Username, password, and email address: Depending on the kind of security framework that is used (or not) these may be attributes of a customer (or attributes of a user that is attached to a customer), or they may even be completely addressed by the security framework and ignored in the conceptual model. For now they are left as security issues, and not included in the conceptual model.

From the information collected above, the preliminary conceptual model may be refined, and it would become similar to the one shown in Figure 6.59, where new classes and attributes are highlighted.

image

FIGURE 6.59 The second version of the conceptual model, refined after the analysis of use case 01: Order books.

Note that a single use case added significant new information to the model. This is no coincidence, because that use case was considered the most important in the system and thus the first to be detailed in iterations. Its complexity has a lot to contribute to the comprehension of the information structure that the system should manage.

Not every association in Figure 6.59 had its multiplicities defined. The UML default for undefined role multiplicity is 1, but the situation in Figure 6.59 is that associations with no multiplicity defined were simply not analyzed up to this point and are considered “to be defined.”

6.8.2 Dependent and independent concepts

A concept is dependent from others if it needs to be associated to them in order to make sense, that is, to represent information that is minimally meaningful.14 Looking at Figure 6.59, it can be seen that an order would not make sense unless it was associated to a customer and to a set of items. Without those associations, the concept of Order would not make sense. The order also has other associations in that figure, but they are optional.

A concept is independent if it has a meaning even without being associated to others.15 For example, the Publisher concept may be understood just from its attributes, without being associated to other concepts. The existing associations for a publisher are optional. Thus, the Publisher concept, in that sense, is independent.

But, what purpose does this distinction serve? It was discussed in Chapter 5 that only the simplest concepts may be managed by CRUD use cases. Dependent concepts should not be considered simple in principle, while independent concepts may be simple in principle.

In Figure 6.59, almost all the concepts are dependent. For example, a delivery depends on an order, a confirmation depends on a delivery, and so on. Only Publisher, Book, and Customer are independent concepts and candidates to be managed by CRUD use cases.

Concepts that are managed by CRUD use cases are usually those that can be accessed directly when information is being retrieved from a system. Although adding the façade-controller class to the model could wait for design modeling activities (Chapter 9), it can be added now to indicate which concepts are independent ones. In principle, only independent concepts have mandatory links to the controller class. Being linked to the controller class means that the instances of the class may be accessed directly. For example, an instance of Book may be accessed directly by its ISBN. However, an instance of Item is not accessible directly. To access an Item one has to navigate from a Book or an Order. Thus, the Item is not linked to the façade-control class.

Although Book is an independent class, it was not linked to the controller because it has a mandatory association to another independent class: the Publisher. In this case, any book may be accessed by looking at the set of books of the publishers. If later it is discovered that books must be accessed directly, independently from its publisher or that any other concept needs this kind of access, then (derived) associations to the controller may be created as needed, but they are not created by default for every concept, to avoid increasing coupling among classes.

There are, therefore, two main paths to reach information in the model of Figure 6.60: from a publisher, and from a customer. All other concepts are reached by starting at one of those. Later, as mentioned, information needs may require defining other paths. In Chapter 9, we see that an order must also be accessed directly, because a number of system operations need to obtain an order by its number or date independently of who the customer is or what books are in it.

image

FIGURE 6.60 Refined conceptual model with a façade controller.

6.8.3 How to find associations

If the information related to concepts and attributes is easily found in the use case texts, the associations are not. As mentioned before, use cases indicate many operations that transform information, but one must seek for clues about associations.

So, how do we find associations between complex concepts? There are at least two rules that can be used:

Dependent concepts (such as Order, Payment, Cancellation, etc.) should be necessarily associated to the concepts that complement them (which may be dependent or independent).

Associative information, that is, associations that are not mandatory, but that complement the information in the model (such as “a person may own a car”), should be represented by associations.

Sometimes, associative information appears in the use case texts as concepts. For example, an order could be an association between a customer and books), but it is sufficiently complex to be represented as a concept. As an order is a dependent concept, there are associations between those concepts and their complements.

When one states that a person may own a car, that information should be represented by an association. Many professionals who work with programming but not modeling could produce models similar to the one presented in Figure 6.61. However, this is unsuitable, because (first) attributes should not have concepts as type, and (second) the model is disguising a real association.

image

FIGURE 6.61 An attribute disguising an association.

It is also unsuitable to use foreign keys (Date, 1982), as shown in Figure 6.62, because that also disguises associations. This mistake is commonly made by modelers used to design relational databases. Foreign keys must not be used in conceptual modeling because they are an implementation technique.

image

FIGURE 6.62 An association disguised as a foreign key attribute.

Thus, when two complex concepts are related to each other, the construct to be used is the association (Figure 6.63).

image

FIGURE 6.63 Suitable representation for the situation shown in Figures 6.61 and 6.62.

The example of Figure 6.63, contrary to the others, respects a cohesion rule that states that a concept should only contain its own properties. As the ID is an attribute of the owner, it should not be represented as an attribute of a car (as in Figure 6.62). Another reason to have visible nondisguised associations is more practical: it is easier to see which objects have references to others. Later (Chapter 9), we discuss how these visibility lines may be used for designing effective and good quality object-oriented code.

6.8.4 Example of iterative construction of the conceptual model

It was mentioned before that the Unified Process is use-case driven and architecture centered. But, what does that mean in practice? We have seen already how to identify and detail use cases, and we have also seen that they can be used as a source of requirements for refining the conceptual model, which is the basis for the design class diagram, an important part of the system architecture. Section 6.8.1 showed how the preliminary conceptual model could be refined with information from the first detailed use case (Order books).

Applying that process again, simulating a second iteration for use case 02 Pay order, new concepts and attributes are discovered (Figure 6.64).

image

FIGURE 6.64 Main flow of use case 02 Pay for books with candidate concepts and attributes identified.

The elements identified in this use case are:

Delivery addresses: As a customer may have more than one delivery address and as addresses are used to calculate delivery fees, they may not be represented by a simple attribute, but instead are represented by a class.

• The second occurrence of delivery address refers to the specific address associated to the current order. Thus, a new association is found between an order and one address.

Delivery fee: Attribute of the order. But from where is this value obtained? If requirements are further analyzed it would be discovered that different cities have different fees that depend fundamentally on the distance from the city to the company headquarters. Thus a new class is created (City), which is associated to Address, and the default fee for each city is defined as an attribute of that class.

Credit cards: New concept. Should be associated to a customer.

Flag: Probably not an attribute, but a complex concept associated to a credit card.

Card for payment: An association between an order and a customer’s credit card.

Credit card operator: It is in fact an external actor; its data may be associated to the credit card flag.

Card number, owner’s name, validity, security code: Attributes of a credit card.

Purchase total value: Same as order total value.

Code of the store: Not an attribute of the bookstore, as might be thought. This code identifies the bookstore for each card operator. As different operators may provide different codes, this attribute should be represented in the credit card flag concept, unless a network of stores is being modeled.

Approval: This happens when an authorization code is received (see next item).

Authorization code: Can be thought of as an attribute of the order. But it may only exist when a credit card is already linked to the order. Thus, it would be better placed as an attribute of the association between credit card and order.

Tracking number of the delivered package: May be an attribute of the delivery.

The new elements are highlighted in Figure 6.65, which is the third version of the conceptual model for the Livir example. Notice that there are still some concepts with no attributes and some associations are left with undefined multiplicity. This is because the use cases analyzed to this point did not produce information to refine those elements. They would be refined latter when other use cases are expanded and their information incorporated in the conceptual model.

image

FIGURE 6.65 Conceptual model refined with information from the main flow of the use case of the second iteration: 02 Pay order.

Observe that just the main flow of this use case was used in the example. Alternate flows of this use case still need to be analyzed and included. Recently, Jacobson et al. (2011) have proposed the use case 2.0 technology, which specifically suggests that a use case should be addressed in slices, and not as an indivisible whole.

At least two invariants still should be added to the diagram of Figure 6.65 in order to avoid the existence of inconsistent information: the address of the order must be one of the addresses of the order’s customer and the credit card used to pay the order must be one of the credit cards of the customer. Those invariants may be defined in the Order class as

Context Order

inv:

self.customer.address->includes(self.address)

and

self.customer.creditCard->includes(self.creditCard)

The OCL predicate includes verifies if the object received as an argument is included in the set. It is equivalent to the math operator “⊇”. For example, self.customer.address->includes (self.address) means self.customer.addressself.address, that is, self.customer.address contains self.address. It is assumed that if the element received as an argument is the empty set, then the expression is true. Thus, if the delivery address and credit card were not yet defined, then the invariant is not being violated.

The analysis of the second use case has incremented the conceptual model with a significant number of new classes and attributes. The idea is that the quantity of novelties decreases as the iterations advance, because, in the end, only CRUDs of elements already studied and reports with information that should already be in the system will be addressed. It is not expected that they will bring any new information to the conceptual model.

Observe that inverting that order would leave for the final iterations the insertion of many classes and attributes, and this would require a lot of rework in the design, and some architecture refactoring would possibly be needed in order to accommodate those needs. That is why it is so fundamental to initiate the project with the most complex use cases and only later incorporate the simpler ones into the architecture.

6.9 The process so far

Image

Image

6.10 Questions

1. Try to imagine a real world situation where the right structure to be used is a sequence. Remember that a real sequence allows elements to be repeated and assigns position to elements. Try not to get fooled by natural language use of the word “list.” A “grocery list,” for example, is not a sequence, because elements do not repeat and their position in the list is irrelevant; a student roll call may be organized in alphabetical order, but again, repetition is not allowed and the order is again irrelevant although convenient. Thus, those are not real sequences.

2. What is the purpose of the controller class? What is its relation with dependent and independent concepts?

3. Why should an attribute not be typed with a class name? Why should an attribute not be used to reference another class?

4. Elaborate a list of concepts and subconcepts (subtypes of the original concept, as, for example, dog and beagle) from common sense. Then, try to identify the type of each relation: structural, associative, or temporal. Try to have at least one example of each type in your list.

5. What is the difference between a normal association, an aggregation, and a composition?

6. List some examples of data types that could be defined as primitive.


1Not necessarily, because many analysts may chose natural language or other specification languages. However, as OCL is part of the UML package, it is advisable to use it.

2At this point, some readers that are also programmers could be worried about performance issues with the code that will be used to implement derived attributes. As they are by definition “calculated,” it seems a waste of processing time to repeat those calculations if the original values of cost and price do not change. However, the readers can stay calm because code optimization mechanisms are available for derived attributes. For example, the value calculated for a derived attribute may be kept in the cache and recalculated only when one of its components is changed. For example, profit has to be recalculated only when the instance of Book changes the values of price or cost.

3The ISBN formation rule is explained in http://www.isbn.org/standards/home/isbn/us/isbnqa.asp.

4Some languages such as Smalltalk allow constants to change their value in runtime, but this is not usually the case and is not recommended for most applications.

5A design pattern that states that a class with a single instance may be accessible globally.

6See also an example in Figure 6.18.

7In fact, in OCL, even a single object is considered a collection with a single element. This is equivalent to the natural notion of a set, but not to the mathematical notion, because in set theory, a set with one element is not the element. In OCL a set with one element and the element are the same thing.

8In the case of a set of people p, if someone wants to get the set of all ages, she could write p.age. However, the size of the set is not a property of the people; it is a property of the set structure. Thus, to obtain the size of the set the expression p->size() should be used. If it was written as p.size, then it would be representing the set of the sizes of each person, not the size of the set.

9“An association may represent a composite aggregation (i.e., a whole/part relationship). Only binary associations can be aggregations. Composite aggregation is a strong form of aggregation that requires a part instance be included in at most one composite at a time. If a composite is deleted, all of its parts are normally deleted with it. Note that a part can (where allowed) be removed from a composite before the composite is deleted, and thus not be deleted as part of the composite. Compositions may be linked in a directed acyclic graph with transitive deletion characteristics; that is, deleting an element in one part of the graph will also result in the deletion of all elements of the sub graph below that element” (Object Management Group, 2011).

10Just try to search Google for images with the keywords “UML” and “inheritance.” You will see lots of examples of bad use of inheritance, as, for instance, Person as a generalization of Student and Professor.

11More specifically, an object is also an instance of all of its superclasses (Section 6.6.1). The idea is that the set of superclasses should not change after the instance is created.

12Methods are only considered when design classes are being modeled. Remember that conceptual classes do not have methods.

13The monotonic decreasing case can be considered here too (a transition that can only remove properties from an instance).

14There is a parallel between dependent concepts and transitive verbs. The sentence “He opened” does not make sense, because the verb needs a complement, as for example, “He opened the can.”

15A parallel exists between independent concepts and intransitive verbs. The sentence “He slept” makes sense because the verb does not require a complement. However, even intransitive verbs may have supplemental information (for example, “He slept for three hours”), as independent concepts do.