INTRODUCTION
Starting with an object-oriented example to set the stage, this article explores generalization (and specialization) in use case modeling. Part one outlines key concepts and addresses generalization of use case actors. Part two covers generalization of two additional use case model elements.
SETTING THE STAGE
The best way to promote a common understanding of generalization is through a simple object-oriented example, especially since use case models are founded on object-oriented principles (i). Most of the concepts encountered in the example trace back to [1] and [2], which strike me as highly informative books.
An object-oriented example
Imagine an object-oriented inventory system for an organization’s tables and chairs. In the real world, each table and each chair is a physical object. In the electronic world of the inventory system, each physical table is represented as an electronic object of type Table and each physical chair is represented as an electronic object of type Chair, so that:
- Each object’s type indicates what the object is in and of itself (independent of any context), for its entire existence (the type doesn’t change during the object’s lifetime).
- An object’s type corresponds to the concrete class in which it is created (ii), so that an object of type Table is created in the concrete class Table and an object of type Chair is created in the concrete class Chair.
The Table and Chair classes are defined beforehand and specify the kinds of characteristics (e.g., particular attributes and associations) for which an object created in the class has individual characteristics (e.g., specific attribute values and links). For example, a Chair object has a True or False value for the Chair class’s hasArmRests attribute.
In defining these concrete classes, we may notice that they have certain kinds of characteristics in common (e.g., they both have the ‘color’ attribute). This is a clue that we can generalize these classes to a superclass, like Furniture Piece, to represent what tables and chairs have in common.
- Since each object that belongs to the Furniture Piece class is either a Table or a Chair, the Furniture Piece class is said to be abstract, to indicate that it cannot be instantiated (there will be no objects of type Furniture Piece).
- Another way to express this is that the Furniture Piece class is ‘completely partitioned’ (it is completely subdivided into subclasses).
Furniture Piece represents a ‘generalization’ of (the objects in) its subclasses, as depicted in the following diagram.
Class hierarchies
Generalizing classes creates a class hierarchy. In this example, it starts with a flat structure of two concrete classes that reflect what their objects are in and of themselves, which is then expanded into a hierarchy by adding an abstract superclass that represents what objects in the two subclasses have in common.
The class hierarchy in the diagram above is represented below as a class diagram, expanded with some attributes (iii), an association, and some operations (see later).
Inheritance
A key feature of a class hierarchy is inheritance, in which kinds of characteristics defined for a superclass are inherited by its subclasses.
Inheritance is a class construct, not an instance one.
- This means that, for example, the Table and Chair classes inherit the color attribute from the Furniture Piece class, such that each Table and Chair object must be assigned a value for the color attribute at the time of the object’s creation.
- It does not mean that each Table and Chair object inherits its particular color (a color attribute value) from a corresponding Furniture Piece object, because there are only Table and Chair objects, no Furniture Piece objects.
Likewise, the Table and Chair classes inherit the association with the Location class from the Furniture Piece class, such that each Table and Chair object may have a link to an ‘assigned location’.
Specialization
A class hierarchy can also result from specialization. This means introducing a subclass, and representing how it differs from its superclass by defining kinds of characteristics that apply to the subclass but not to the superclass (iv).
- To a superclass, a subclass is a ‘specialization’ of the superclass.
- To two or more subclasses, a shared superclass is their ‘generalization’ (v).
In the earlier class diagram, Table and Chair are specializations of Furniture Piece, where Table has the maxNumberOfPeople attribute (but Furniture Piece doesn’t) and Chair has the hasArmRests attribute and the getSeatingPosition operation (but Furniture Piece doesn’t).
The following three sections describe additional examples of specialization.
Deferring methods to subclasses
Apart from inheriting attributes and an association, Table and Chair also inherit the getCapacity operation (vi). An operation on a class represents that an object in the class is capable of a named behavior, in this case, getting its capacity.
- Capacity represents the number of people the corresponding physical object can accommodate.
- A Table’s capacity is indicated by the maximum number of people that can sit around it, while a chair’s capacity is always equal to one.
The Furniture Piece’s operation is shown in italics to indicate that it’s abstract. This means that Furniture Piece doesn’t provide a method for this operation but leaves it up to its subclasses to do so (vii). In contrast, Table and Chair show the operation in straight font to convey that it’s concrete. This means that each subclass provides its own method for the operation.
- Thus, when a Table object is asked to perform the operation, the Table class’s method is to return the Table object’s value for the maxNumberOfPeople attribute, and when a Chair object is asked to perform the operation, the Chair class’s method for this operation is to return 1.
So, providing a method for the superclass’s operation is deferred to the subclasses.
Overriding a method
An alternative pattern for modeling the getCapacity methods is as follows.
- Furniture Piece’s getCapacity operation is concrete and its method is to return 1 (i.e., this is the default method).
- Chair inherits the method from Furniture Piece, but Table defines its own method, which is to return a Table object’s value for the maxNumberOfPeople attribute.
Thus, Table’s own method overrides Furniture Piece’s default method.
Adding an operation and its method
Chair has an operation over and above the one it inherits.
- The getSeatingPosition operation returns “in” or “on” for a given Chair object.
- The corresponding method gets the Chair’s hasArmRests attribute value, and returns “in” or “on” based on whether this value is True or False, respectively.
The added operation helps to define Chair as a specialization of Furniture Piece.
Type and class
In philosophy, there is a difference between a type (which represents a certain concept, like chair) and a class (which is a collection of objects, such as tables and/or chairs).
In class diagrams, these two aspects are combined, such that a class represents both a concept (through the kinds of characteristics that characterize it) and a collection (of objects that have individual characteristics for those kinds of characteristics).
Even so, there is still a linguistic distinction, because an object ‘is of’ a certain type but ‘belongs to’ (is a member of) a class. At minimum, an object that is of a certain type belongs to the concrete class in which it is created; if that class has any superclasses, the object belongs to those as well, albeit indirectly.
Type correspondence
A key measure of the correctness of a class hierarchy is type correspondence. This means that the statement ‘ is a type of ’ must be true for each combination of subclass and superclass (representing the subtype and the supertype, respectively, keeping in mind that a class represents both a type and a collection).
- For example, ‘a Table is a type of Furniture Piece’ and ‘a Chair is a type of Furniture Piece’.
Let’s now turn to generalization (and specialization) in use case modeling.
GENERALIZING ACTORS
Why actors can be generalized
In [3], Actor is a subclass of BehavioredClassifier, which is a subclass of Classifier. Because generalization is a feature of Classifier, Actor inherits this feature from that class. In other words, actors can be arranged in an actor hierarchy.
An example
A concrete use case has one and only one initiating actor (viii), but what if some of a system’s use cases can be initiated by users of different kinds, such as Contact Centre Specialists and Customer Statement Specialists? Actor generalization solves that problem, as illustrated in the following diagram.
Actor generalization (and specialization) creates an actor hierarchy.
What an actor means
The earlier object-oriented example deals with electronic objects internal to a system, each of which comes into existence by being created in a concrete class. In contrast, the notion that actor instances are created in concrete actors doesn’t apply, because:
- An actor represents actual entities that can use a system (e.g., actual people, actual systems, actual functions), which already exist in their own right.
- An actor represents a role some entity may play, not what the entity is in and of itself.
When an actor is concrete, it means that entities are assigned to it, not that they are created in it.
Two patterns
In fact, we need to be aware of two modeling patterns, for which I use the following terms and definitions.
- Classification: arranging entities in classes based on what the entities are in and of themselves, such that an entity belongs to one and only one concrete class that reflects the entity’s type, and belongs to that class for its entire existence (ix).
- Categorization: assigning entities of one or more types to categories, based on point-in-time rules, judgment or preference, such that an entity may belong to multiple categories at once, and may belong to a category for part(s) of its existence.
Thus, the earlier class hierarchy reflects classification, while the above actor hierarchy represents categorization. The next diagram shows the latter (x).
Like the Furniture Piece class in the object-oriented example, the Customer Service Specialist actor is abstract, because it is completely partitioned (i.e., completely subdivided into subactors).
Unlike the Furniture Piece class, the Customer Service Specialist actor is not ‘disjoint’, but ‘overlapping’ (as [3] calls it), because a given person can in principle belong to multiple subactors at once (a clue we’re dealing with categorization, not classification).
Type correspondence
As for a class hierarchy, ensuring type correspondence is a must for an actor hierarchy, albeit that here the types are strictly the actor names themselves, rather than the types (conceptual or otherwise) of actual users (e.g., Person).
- In this case, ‘a Contact Centre Specialist is a type of Customer Service Specialist’ and ‘a Customer Statement Specialist is a type of Customer Service Specialist’ are true, so the actor hierarchy is appropriate.
Actor hierarchy antipattern
Sometimes, use case texts advocate adding a generalization relationship between two concrete actors. This is only appropriate when any and all members of the subactor are always members of the superactor as well. If not, this kind of actor hierarchy is a misrepresentation, as the following diagram illustrates.
Below are two more examples of an actor hierarchy.
To avoid an inappropriate actor hierarchy, add an abstract superactor as shown earlier, and let the overlapping nature of the concrete subactors handle the scenario where a person can belong to both subactors, through individual assignment.
NOTES
(i) To keep it simple, the example only deals with one abstract superclass and two concrete subclasses.
(ii) Some refer to instantiating an object, which seems inappropriate. Instantiation means representing a concept (e.g., chair) by an instance (e.g., a chair), so it’s the concept that is instantiated, not the instance. In object-oriented terms, a concrete class can be instantiated (can have objects created in it), but an abstract class can’t.
(iii) While most attributes have a data type like Boolean, Integer or String, the data type of each of the remaining attributes refers to an enumeration, which is a list of the attribute’s allowed values.
(iv) Specialization isn’t necessarily the opposite of generalization. You can’t generalize a single class to a superclass, but you can specialize a class to a single subclass. The latter means that:
- The class is concrete to begin with (objects are or can be created in it).
- A subset of the class’s objects are moved to the subclass (i.e., they’re deleted from the class and created in the subclass with a new type that equals the name of the subclass).
- The class retains its remaining objects (whose type equals the name of the class).
- In other words, the class is not completely partitioned.
(v) This article avoids ‘generalized’ and ‘specialized’ as qualifying terms, because they’re ambiguous (e.g., does ‘generalized’ apply to the two or more classes being generalized, or to the class that represents the generalization?); the unambiguous qualifiers ‘super’ and ‘sub’, as well as ‘generalization’ and ‘specialization’, are used instead.
(vi) Class operation: to be performed by a class as a whole (e.g., create an instance). Instance operation: to be performed by a specific object in a class. In this article, each operation is an instance operation.
(vii) Method: a representation of how a class or an object will respond when asked to perform a given operation.
(viii) The examples in 16.3.6 of [3] where “more than one actor instance is involved in initiating the use case” can be represented more simply as one initiating actor and one supporting actor.
(ix) There are entities that change types during their existence (e.g., a caterpillar changes to a butterfly), but such type changes are outside the scope of this article, because they usually don’t have to be dealt with in a typical system.
(x) See 16.3.1 in [3], “Actors may represent […] multiple different instances.”
Don’t forget to leave your comments below.
REFERENCES
[1] Meilir Page-Jones, Fundamentals of Object-Oriented Design in UML, 4th Printing, September 2000, Addison-Wesley.
[2] Bruce F. Webster, Pitfalls of Object-Oriented Development: A Guide for the Wary and the Enthusiastic, 1995, M&T Books.
[3] Object Management Group (OMG), OMG Unified Modeling LanguageTM (OMG UML), Superstructure, Version 2.4.1.