Now that you know how to use simple UML words and sentences, let's consider the object-oriented paradigm on which the UML's semantics are based. We'll look at how object-oriented concepts enable us to view the world around us, and at how the paradigm's principles enable us to better manage change and complexity.
The object-oriented paradigm is based on a few key concepts that enable us to view the world around us. The next few sections discuss these key concepts.
Figures Figure 2-3 through Figure 2-5 represent general sentences, because they don't identify particular projects, managers, teams, and so forth. The general concepts shown in the sentences are known as classes, and the general relationships are known as associations. Similar to natural languages, we can also communicate in the UML using specific sentences involving specific projects, managers, teams, and so forth, where specific concepts are known as objects and specific relationships are known as links.
A class defines a type of object and the characteristics of its objects, and an object is an instance of a class. For example, Figures Figure 2-4 and Figure 2-5 show three classes, including Manager, Team, and Project. We can have many managers, teams, and projects, and each specific manager, team, and project is an instance or object of its class. In the UML, a specific concept is shown using the same symbol as its general concept. The symbol is labeled with a specific name followed by a colon followed by the name of its general concept. The entire stringspecific name, colon, and general nameis fully underlined. Both names are optional, and the colon is only present if the general concept is specified. Figure 2-6 shows a specific class for each of the three objects shown earlier in Figures Figure 2-4 and Figure 2-5.
An association defines a type of link and the characteristics of its links, and a link is an instance of an association. A specific relationship is shown as a line path and may be labeled with the fully underlined name of its general relationship. Figure 2-6 shows two specific links of the associations shown earlier in Figures Figure 2-4 and Figure 2-5.
Figure 2-6, a specific sentence based on the general sentence shown in Figures Figure 2-4 and Figure 2-5, shows that Si, who is a manager, manages the Eagle project and leads an anonymous or unnamed team. This notation and naming convention between a class and its instances, or an association and its instances, is used throughout the UML and is known as a type-instance dichotomy.
The object-oriented paradigm views the world as a collection of unique objects, often referred to as a society of objects. Each object has a lifecycle where it knows something, can do something, and can communicate with other objects. What an object knows and can do are known as features. For example, a manager knows his or her name, can initiate or terminate a project, and can communicate with a team to lead the team to successfully execute the project. Features belong to two broad categories or types: attributes and operations.
Something that an object knows is called an attribute, which essentially represents data. A class defines attributes and an object has values for those attributes. Even if two objects have the same values for their attributes, the objects are unique and have their own identities. In a UML diagram, a class may be shown with a second compartment that lists these attributes as text strings. Likewise, an object may be shown with a second compartment that lists these attributes as text strings, each followed by an equal symbol (=) and its value. Only attributes we wish to communicate are shown; other attributes that are not important for us to communicate on a given diagram need not be shown. Associations and attributes are known as structural features, because they communicate the class's structure similar to how structural modeling is used to communicate structure as discussed in Chapter 1.
Figure 2-7 elaborates on Figure 2-4 and shows that a manager has a name, a team has a description, and a project has a name, start date, and end date.
Figure 2-8 elaborates on Figure 2-6 showing various objects with values for the attributes introduced in Figure 2-7.
Something an object can do is called an operation or specification and essentially represents processing. How an object does the processing for a given operation is known as the operation's method or implementation. For example, when using a programming language, we declare functions or procedures and define their bodies (lines of code) that determine what the functions or procedures do when they are invoked and executed; a function's declaration is the operation, and the body definition is the method. A class defines operations and methods that apply to its objects. A class may be shown with a third compartment that lists these operations as text strings. A class's methodsthe code actually implementing the operationsare not shown on a class, but may be described using other UML modeling techniques. An object does not have a third compartment, because all the objects of a class have the same operations and share their class's methods. Likewise, only operations we wish to communicate need be shown on a given diagram. Other operations that are not important for us to communicate on a given diagram need not be shown. If attributes are not shown, an empty attributes compartment must be shown such that the third compartment is used to list the operations. Operations and methods are known as behavioral features, because they communicate a class's behavior similar to how behavioral modeling is used to communicate behavior as discussed in Chapter 1.
By showing two operations, Initiate Project and Terminate Project, Figure 2-9 shows that a manager may initiate or terminate a project. Notice that the second compartment for Manager is empty, because I'm focusing only on a manager's operations.
Figure 2-10 combines Figure 2-7 and Figure 2-9 by showing the attributes and operations for each class on the same diagram.
In the object-oriented paradigm, communication from a sender object to a receiver object is used to convey information or request processing. For example, we don't initiate a project for a manager but communicate a request to the manager to initiate the project. Once the manager receives the request, an operation is invoked to handle the request, and the manager executes the method associated with the operation. The sending of a request and reception of a request are events, or occurrences. Communication between objects via their links is called a stimulus, and communication between classes via their associations is called a message. A stimulus is an instance of a message similar to how an object is an instance of a class and a link is an instance of an association. The sender is known as the client, and the receiver is known as the supplier. A message or stimulus is shown as an arrow attached to an association or link pointing from the sender toward the receiver and labeled with a sequence number showing the order in which the message or stimulus is sent, followed by a colon followed by the name of the operation to be invoked.
Figure 2-11 shows that a manager assigns activities and tasks to a team based on a project's requirements.
Figure 2-12 shows a specific interaction between Si (who is a manager), the Eagle project, and the team.
The object-oriented paradigm is based on four principles that enable us to better manage change and complexity. The next few sections discuss these principles.
Concepts and relationships are known as abstractions. Classes and associations are general abstractions, and objects and links are specific abstractions. A good abstraction is well defined and includes essential information required for understanding it, but excludes any irrelevant or incidental information. For example, when communicating about managers, it is essential that we know their names, but it is not essential for us to know how many pets they own or the types of pets they own, if any. Likewise, by considering various managers, we can determine what similarities and differences they have that allow us to classify them as managers. By using well-defined abstractions, we can better manage complexity by focusing on what is essential rather than being distracted by what is incidental.
Combining attributes and operations to form classes and objects and hiding methods behind operations is known as encapsulation.
Combining attributes and operation to form classes and objects is also known as localization. By combining attributes and operations into single units, we can better manage change and complexity by reducing the number of places we have to consider when a change occurs. For example, when there is a change to the Manager class, such as a need to track the manager's years of experience, we simply need to go to the class and update its attributes or operations rather than go to one location to update the manager's data (or attributes) and another location to update its processing (or operations).
When classes or objects communicate, the client is usually interested only in the results of the operation and not the method the supplier uses to perform the operation; thus, a method may be completely hidden from its clients. For example, a manger is interested in having the team execute a project, but the manger is not so much interested in the intricate details of how the team executes the project. An attribute may also be made inaccessible or hidden from clients in that it must be accessed via operations, called getters and setters, which retrieve and set the value of the attribute. For instance, how the budget associated with a project is stored may be hidden from clients, in that it is either stored in a database or a flat file, and is accessible via getter and setter operations.
Hiding a method behind an operation is also known as information hiding. Doing this allows us to better manage change and complexity, because we are able to modify a class's method without impacting its clients who use the operation implemented by the method. For example, when a manager directs the team to execute a project, the team may use various techniques, and may change techniques without impacting the manager. Also, the getters and setters for the budget associated with a project may be changed to store the budget in a database instead of a flat file, or vice versa, without impacting clients.
Figure 2-13 shows the classes that represent requirements and systems based on the requirements for the project management system case study. Note that requirements and systems are work products with some similar attributes and operation but different methods for validation and various attributes unique to their classes. That is, both systems and requirements have a Percent Complete attribute and a Description attribute, but requirements also have a Media attribute while systems have a Platform attribute. While both systems and requirements have a Validate operation, requirements also have a Publish operation while systems have a Deploy operation. We can use a generalization to capture and reuse their commonality. A generalization is used between a more general class and a more specific class to indicate that the more specific class receives the attributes, relationships, operations, and methods from the more general class. A generalization is shown as a solid-line path from the more specific class to the more general class, with a large hollow triangle at the end of the path connected to the more general class.
Figure 2-14 shows how a generalization is used to communicate that both requirements and systems are work products that have a description, percent complete, and may be validated. Notice that the Validate operation has been moved into the Work Product class, similar to the Description and Platform attributes, but the Validate operation also appears in the Requirement class and System classes. In the next section, I will discuss why the Validate operation appears in all the classes. By using a generalization, we can better manage change and complexity. We gain the ability to reuse existing abstractions to define new abstractions, and changes we make to a more general class are propagated to its more specific classes. For example, we can use the Work Product class to define other types of work products such as user documentation, installation and administration manuals, and so forth as necessary in the future.
Figure 2-14 shows that the Validate operation appears in all the classes. It is identified or declared in the Work Product class, perhaps with a default method, but the Requirement class and System class provide their own methods for validation. Hence the need for the Requirement and System classes to list their own Validate operations. Had these classes simply inherited the default Validate functionality from the Work Product class, you wouldn't list the Validate method again. The ability to have multiple methods for a single operation is called polymorphism.
Because a generalization between a more general class and a more specific class also indicates that objects of the more specific class are simply specialized objects of the general class, objects of the specific class may be substituted for objects of the general class. For example, requirements and systems may be substituted for work products. Simply applying the Validate operation on a work product without knowing its actual class causes the appropriate method to be invoked. By using polymorphism, we can better manage change and complexity by reusing operations with new methods, and we can communicate requests without having to manage which actual methods are invoked. That is, we can manipulate requirement work products, system work products, and other specific types of work products simply as general types of work products. For every requirement work product, the Validate method provided by the Requirement class is invoked to handle validation requests. For every system work product, the Validate method provided by the System class is invoked to handle validation requests, and so forth for any other types of work products.