3.1 Types and classes

The first thing we need to know is how to represent objects. Figure 3 shows how classes and instances are represented. Unfortunately, UML does not distinguish adequately between types and classes notationally; but we can add the stereotype «type» to the class icon to show the difference. Stereotypes are tags that can be added to objects to classify them in various ways. This useful idea was originally proposed by Wirfs-Brock and McKean (1996) but in the current version of UML (1.4) a class is allowed only one stereotype, which rather destroys their point. CASE tools then use the stereotype to render the object graphically, as we shall see later. We are convinced, with the majority of methodologists, that future versions of UML will permit multiple stereotypes and will assume it is so in this text. Users of current CASE tools can use free-text notes to do this. Notes are also illustrated in Figure 3. Notice that instance names are always underlined; otherwise the notation for an instance is exactly the same as that for a class (type).

A stereotype indicates a variation in the way the item should be interpreted, dealt with by tools, and presented. Standard stereotypes also include: «interface», «type» and «capsule». Stereotypes can be added to classes, associations, operations, use cases, packages, and so on. Actors are just objects, tagged with the «actor» stereotype. Most tools just use the stereotypes to display different icons; e.g. pin men. Stereotypes make the language extensible, adding extra meaning to the basic pieces of syntax, but to preserve the communicability of models please consult your friendly, local methodologist before inventing more.

In approaching object-oriented analysis we need to deal first with types and only during design is it appropriate to think of classes. Therefore, rather than use the stereotype, we interpret the class icon as a type unless otherwise noted.

Figure 3 Types and their instances.

We have adopted the convention that classes (which are collections of instances) are named in the plural, while types (which represent a single concept) are named in the singular. It should also be noted that rôles, such as the rôle of being an employee, are not the same as types or classes. The reason is that in object-oriented programming an instance belongs to its class forever; whereas a person can stop being an employee - on retirement say.

UML has no adequate distinction for rôles: although the short form shown in Figure 3 is the official usage, it is so useful for type diagrams as to make the restriction intolerable. We therefore usually model rôles as separate objects and indicate rôles with the stereotype «role» when the context so demands.


Figure 4 Generic types or templates.

Recall that we can distinguish between the features of a class and the features of its instances. Class methods and attributes refer to properties of and operations on entire collections. Operations that apply to instances, such as calculating a person's age from their date of birth, are called instance operations, and operations which apply to entire classes, such as calculating the average age of all employees, are class operations. Similarly there are instance attributes and class attributes though these are rarer.

The operations and attributes of an object are called its features. The features (and possibly the name) constitute the signature of the object. It is often useful to think of the features of an object as responsibilities. Attributes and associations are responsibilities for knowing. Operations are responsibilities for doing. Generic types (sometimes called templates) are shown as illustrated in Figure 4.

One of the great advantages of a conventional database management system is the separation of processes and data which gives a notion of data independence and benefits of flexibility and insulation from change, because the interface to shared data is stable. The data model is to be regarded as a model of the statics of the application. With object-orientation, processes and data are integrated. Does this mean that you have to abandon the benefits of data independence? Already in client-server relational databases we have seen a step in the same direction, with database triggers and integrity rules stored in the server with the data. With an object-oriented approach to data management it therefore seems reasonable to adopt the view that there are two kinds of object, which we call domain objects and application objects. Domain objects represent those aspects of the system that are relatively stable or generic (in supplying services to many applications). Application objects are those which can be expected to vary from installation to installation or from time to time quite rapidly. This approach resurrects the notion of data independence in an enhanced, object-oriented form. A conventional data model is a view of the domain objects, which latter also include constraints, rules and dynamics (state transitions, etc.). The goal is to make the interface to this part of the model as stable as possible. The domain objects form the shared object model. Most interaction between components is via this model. We can go further and distinguish interface objects which are those whose sole raison d'etre is to enable communication, either with humans or with other systems and devices.

As an example of these distinctions in most business domains, Products and Transactions are unarguably domain objects, while DiscountCalculators might be a special application object. Classes like Sensors and InputValidators are likely to be interface objects.

These three categories can be regarded as stereotypes. Other stereotypes that are sometimes useful include controllers, co-ordinators, information holders and service providers. As Wirfs-Brock and McKean (1996) point out, such classifications are intentional oversimplifications to be refined during analysis and design.

Attribute facets

The type icon shows lists of associations and operations. Associations are attributes that refer to other types. There are two ways of interpreting them: one can either think of them as shorthand for their corresponding get and set operations or as providing the vocabulary with which the type can be discussed. As shown by Wills (2001) the latter interpretation is the best one for component or system specification, and the associations can then provide the basis for part of the test harness. These viewpoints are both useful in different contexts as we shall see. However, when we come to requirements analysis it is seen that a pointer viewpoint is often more valuable. Attributes are associations to more primitive types that are often left unspecified (such as String or Integer) and that we probably would not include on a structure diagram. What is 'primitive' is a rather subjective decision so that, technically, there is no distinction between attributes and associations.

UML allows classes to be tagged with extra information using the notation {tag=value}. The most useful tags include the following:

Abstract classes are named in italics. In specification, when we are talking about types rather than classes, the notion of 'abstract' does not, of course, make sense.

UML supports the following annotations to, or facets of, associations:

We would use notes or naming conventions to add additional facets of the following types:

Operations are the specifications of an object's methods. UML supports the following facets of operations:

These can also be used to specify the visibility of packages. We will see later that additional facets, such as pre-conditions, are essential.