3.4 Generalizations, Realizations, and Dependencies

While it is common to use types during analysis activities, interfaces during analysis activities and design activities, undifferentiated classes during design activities, and implementation classes during the later part of design and during implementation activities, how are all these elements related? Generalizations, realizations, and dependencies, called specialized relationships, address the question of how undifferentiated and differentiated classes are related. The next few sections discuss these relationships.

3.4.1 Generalizations

A generalization between a more general element and a more specific element of the same kind indicates that the more specific element receives the attributes, associations and other relationships, operations, and methods from the more general element. The two elements must be of the same kind. For example, a generalization relationship can be between two types but not between a type and an interface. Generalization relationships may exist for the following kinds of elements:

  • Types

  • Undifferentiated classes

  • Implementation classes

  • Interfaces

A generalization is shown as a solid-line path from the more specific element to the more general element, with a large hollow triangle at the end of the path connected to the more general element. You'll see examples of this as I discuss each specific type of generalization in the following sections.

3.4.1.1 Types

The project manager, human resource, and system administrator types shown earlier in Figure 3-25 are specific types of human resources. You can model a generalization of these three types to factor out structure and behavior common to all. A generalization between types allows us to reuse a type's attributes, associations, and operations to define a new type. Figure 3-30 shows that the THumanResource type is a generalization of TProjectManager, TSystemAdministrator, and TResourceManager.

Figure 3-30. Generalizations between types
figs/Luml_0330.gif

Because a generalization between a more general type and a more specific type indicates that the more specific type is a specialized form of the more general type, those classes that may play the roles of the more specific type may also play the roles of the more general type. Therefore, Figure 3-30 shows that those objects that play the specific roles of project manager, resource manager, and system administrator may also each play the more general role of a human resource.

3.4.1.2 Undifferentiated classes

The Worker class shown in Figure 3-26 may have a more specialized undifferentiated class of human resource, which itself has more specialized undifferentiated classes, including project managers, resource managers, and system administrators. You can nest generalization relationships for undifferentiated classes as well as types, interfaces, and differentiated classes. For example, project managers, resource managers, and system administrators all could be specializations of a human resource. A human resource, on the other hand, could be a specialization of a worker, or a worker could be a generalization of a human resource. A generalization between undifferentiated classes allows us to reuse a class's attributes, associations, operations, and methods to define a new undifferentiated class. The relationships among the undifferentiated classes just mentioned are shown in Figure 3-31.

Figure 3-31. Generalizations between classes
figs/Luml_0331.gif

Figure 3-30 shows three generalization paths, while Figure 3-31 combines three generalization paths from the ProjectManager, ResourceManager, and SystemAdministrator classes into one path that connects to the HumanResource class. Whenever several paths of the same kind connect to a single element, the UML allows you to combine those paths into a single path as shown in this figure. Also, when paths cross but do not connect, the UML allows you to show this with a small, semicircular jog by one of the paths, as shown for the associations between the Worker class and the UnitOfWork and WorkProduct classes. The jog indicates that the line with the jog does not connect in any way with the other line passing through the jog.

Given a specific class, any immediately more general classes are called parents or super-classes. Any immediately more specific classes are called children or subclasses. General classes that are not parents (i.e., not immediately more general) are called ancestors. More specific classes that are not children (i.e., not immediately more specific) are called descendants. Therefore, Figure 3-31 shows that the Worker class is the parent of the HumanResource class, and the ProjectManager, ResourceManager, and SystemAdministrator classes are the children of the HumanResource class. It also shows that the Worker class is an ancestor of the ProjectManager, ResourceManager, and SystemAdministrator classes, and that these classes are descendants of the Worker class.

Because a generalization between two undifferentiated classes indicates that objects of the more specific undifferentiated class are more specialized objects of the more general undifferentiated class, objects of the more specific undifferentiated class may be substituted for objects of the more general undifferentiated class. Therefore, Figure 3-31 shows that project manager, resource manager, and system administrator objects may be substituted for human resource objects.

3.4.1.3 Implementation classes

A generalization between implementation classes allows us to reuse an implementation class's attributes, associations, operations, and methods to define a new implementation class. Earlier, I raised the possibility of implementing the classes shown in Figure 3-27 as database tables. In such a case, the three implementation classes in Figure 3-27 could all be specialized classes of a database table class. Figure 3-32 shows this by making Employee, WorkOrder, and Artifact into specializations of a more general DatabaseTable class.

Figure 3-32. Generalizations between implementation classes
figs/Luml_0332.gif

Because a generalization between a more general implementation class and a more specific implementation class indicates that objects of the more specific implementation class are specialized objects of the general implementation class, objects of the specific implementation class may be substituted for objects of the general implementation class. Therefore, Figure 3-32 shows that employee, work order, and artifact objects may be substituted for database table objects.

3.4.1.4 Interfaces

The project manager, human resource, and system administrator interfaces shown in Figure 3-28 are more specific versions of the human resource interface. A generalization between interfaces allows us to reuse an interface's operations to define a new interface. The relationships among the interfaces just mentioned are shown in Figure 3-33.

Figure 3-33. Generalizations between interfaces
figs/Luml_0333.gif

Because a generalization between a more general interface and a more specific interface indicates that the more specific interface is a specialized form of the more general interface, those classes that provide the service defined by the more specific interface may also provide the service defined by the more general interface. Therefore, Figure 3-33 shows that those objects that provide the project manager, human resource, and system administrator interfaces also provide the human resource interface.

3.4.2 Realizations

A realization from a source element (called the realization element) to a target element (called the specification element) indicates that the source element supports at least all the operations of the target element without necessarily having to support any attributes or associations of the target element. For example, an undifferentiated class or implementation class may play the role defined by a type and may provide the service defined by an interface, if the class supports the operations defined by the type and interface. A realization allows us to reuse the operations of types and interfaces where a realization element is said to realize its specification elements.

A realization is shown as a dashed-line path from the source element to the target element, with a large hollow triangle at the end of the path connected to the target element. When the target element is an interface shown as a small circle, the realization is shown as a solid-line path connecting the source and interface.

3.4.2.1 Undifferentiated classes

Figure 3-29 shows a list of types and interfaces that the Worker class supports. Based on Figure 3-29, Figure 3-34 shows that the Worker class realizes those types and interfaces. The source element is the Worker class, and the other elements are the targets. Figure 3-29 shows how interfaces and types are used in the various associations between the Worker class and other classes, while Figure 3-34 shows that the Worker class explicitly realizes these interfaces and types independent of how they are used in relationships.

Figure 3-34. Realizations for the Worker class
figs/Luml_0334.gif

Based on Figure 3-29, Figure 3-35 shows the interfaces work products realize. The source element is the WorkProduct class and the other elements are the targets.

Figure 3-35. Realizations for the WorkProduct class
figs/Luml_0335.gif

Because a realization from a source class to a target element indicates that objects of the source class support all the operations of the target element, objects of the source class may be substituted for objects of other classes that also realize the same target element. Therefore, Figure 3-34 shows that a worker object may be substituted for objects of other classes that realize the same types and interfaces as the worker object, and objects of other classes that realize the same types and interfaces as the worker object may be substituted for worker objects. That is, if two objects realize the same type or interface, they may be substituted for one another. Figure 3-35 illustrates this.

3.4.2.2 Implementation classes

Based on Figure 3-27, Figure 3-36 shows that the Worker class may be implemented as an employee table, the WorkProduct class may be implemented as an artifact table, and the UnitOfWork class may be implemented as work order table, if you are to implement your classes in a database management system. This is indicated with the realization relationships between the Employee implementation class realizing the Worker class, the WorkOrder implementation class realizing the UnitOfWork class, and the Artifact implementation class realizing the WorkProduct class.

Figure 3-36. Realizations of undifferentiated classes by implementation classes
figs/Luml_0336.gif

When an implementation class realizes an undifferentiated class, it must also realize the types and interfaces that the undifferentiated class realizes; otherwise, it could not play the roles defined by the undifferentiated class's types and provide the services defined by the undifferentiated class's interfaces.

Based on Figure 3-36 and Figure 3-34, Figure 3-37 shows the types and interfaces the Employee implementation class realizes.

Figure 3-37. Realizations for the Employee implementation class
figs/Luml_0337.gif

Based on Figure 3-36 and Figure 3-35, Figure 3-38 shows the interfaces the Artifact implementation class realizes.

Figure 3-38. Realizations for the Artifact implementation class
figs/Luml_0338.gif

Because a realization from a source class to a target element indicates that objects of the source class support all the operations of the target element, objects of the source class may be substituted for objects of other classes that also realize the same target element. Therefore, Figure 3-37 shows that an employee object may be substituted for objects of other classes that realize the same types and interfaces as the employee object, and objects of other classes that realize the same types and interfaces as the employee object may be substituted for employee objects. Figure 3-38 shows the same for an artifact object.

3.4.3 Dependencies

A dependency from a source element ( called the client) to a target element (called the supplier) indicates that the source element uses or depends on the target element; if the target element changes, the source element may require a change. For example, a UnitOfWork uses the IConsumable interface as a consumer and uses the IProducible interface as a producer; if either interface changes, the UnitOfWork may require a change. Figure 3-29 shows the interfaces used by UnitOfWork.

A dependency is shown as a dashed-line path from the source element to the target element. The dependency may be marked with the use keyword; however, the keyword is often omitted because the meaning is evident from how the dependency is used. Also, notice that a dependency does not have a large hollow triangle at the end of the path, but has an open arrow.

Based on Figure 3-29, Figure 3-39 shows the dependencies between units of work and work products. Notice that a realization may be shown as a dependency marked with the realize keyword, as shown in Figure 3-39 between the WorkProduct class and the IProducible interface.

Figure 3-39. Realizations and dependencies
figs/Luml_0339.gif

Figure 3-40 shows the dependencies between the interfaces discussed in this chapter and the parameter and return types for their operations. For example, IProjectManager must depend on Project, because many of its operations take a Project object as a parameter.

Figure 3-40. Dependencies between interfaces and return types
figs/Luml_0340.gif