Section 2.3. Operations


2.3. Operations

Operations are features of classes that specify how to invoke a particular behavior. For example, a class may offer an operation to draw a rectangle on the screen or count the number of items selected in a list. UML makes a clear distinction between the specification of how to invoke a behavior (an operation) and the actual implementation of that behavior (a method). See "Methods" for more information.

You place operations in a separate compartment with the following syntax:

 visibility name ( parameters ) : return-type {properties} 

where parameters are written as:

 direction parameter_name : type [ multiplicity ]   = default_value { properties } 

Figure 2-13 shows several example operations on a class.

Figure 2-13. Example operations on a class


The syntax elements are:


visibility

Indicates the visibility of the operation. Use the following symbols: +, -, #, or ~ for public, private, protected, or package, respectively (see "Visibility" in Chapter 3).


name

Is a short phrase naming the operation. Operations are usually verb phrases representing actions the classifier should perform on behalf of the caller. The UML specification recommends that the first letter of an operation be lowercase, with all of the following words starting with a capital letter and running together. See Figure 2-13 for an example.


return-type

Is the type of information the operation will return, if any. If no information is returned from the operation (called a subroutine in some development languages), the return type should be void. If the operation does return a value (called a function in some development languages), you should show the type of the returned value, such as another classifier, a primitive type, or a collection. The UML specification states that the return type is optional. If it's left off, you can't assume anything about the return value of the operation, or even if one exists.


properties

Specifies constraints and properties associated with an operation. These are optional; if you don't use properties you don't show the curly braces. See "Operation Constraints" for more information.

Parameter syntax elements are:


direction

An optional part of the syntax that indicates how a parameter is used by an operation. It is one of in, inout, out, or return. in states that the parameter is passed to the operation by the caller. inout states that the parameter is passed by the caller and is then possibly modified by the operation and passed back out. out states that the parameter isn't set by the caller but is modified by the operation and is passed back out. return indicates that the value set by the caller is passed back out as a return value.


parameter_name

Is a noun or noun phrase naming the parameter. Typically the parameter name starts with a lowercase letter, with any subsequent words starting with a capital letter.


type

Is the type of the parameter. This is typically another class, interface, collection, or primitive type.


multiplicity

Specifies how many instances of the parameter's type are present. Can be absent (meaning multiplicity of 1), a single integer, a list of integers separated by commas, or a range of values specified between square brackets separated by "..". An infinite upper bound can be represented as an *; if no lower bound specified, an * means zero or more. See "Multiplicity."


default_value

Specifies the default value of this parameter. The default value is optional. If it isn't present, you don't show the equals sign. Note that UML doesn't specify if a parameter with a default value may be left out when invoking an operation (e.g., C++'s default parameter value implementation). The actual syntax for invoking an operation is language-dependent.


properties

Specifies any parameter-related properties and is specified between curly braces. These are typically defined within the context of a specific model, with a few exceptions: ordered, readOnly, and unique. See "Multiplicity" and "Properties" for more information. Properties are optional for parameters; if they aren't used, don't show the curly braces.

2.3.1. Operation Constraints

An operation may have several constraints associated with it that help define how the operation interacts with the rest of the system. Together, constraints on an operation establish a contract that an implementation of the operation must obey.

Constraints on an operation follow the usual constraint notation and are placed either immediately after the operation signature or in a note attached with a dashed line. See "Constraints" for more information.

2.3.1.1. Preconditions

Preconditions capture what the state of the system must be before an operation can be invoked. Practically speaking, you really can't express the state of the entire system. Instead, preconditions typically express the valid values for parameters, the state of the class owning the operation, or a few key attributes of the system.

The specification explicitly states that the operation doesn't need to check the preconditions in the body of the operation before executing; theoretically the operation will not even be invoked if the preconditions aren't met. In practice, few languages offer such protection. If someone took the time to express them, it is usually in your best interest to verify the preconditions are correct when implementing an operation.

As a developer, preconditions offer you one of the few chances to "cover your butt" and say exactly how you expect things to be when your implementation is invoked; use them.

Figure 2-14 shows several examples of preconditions.

Figure 2-14. Preconditions for operations


2.3.1.2. Postconditions

Postconditions capture guarantees about the state of the system after an operation has executed. Like preconditions, postconditions typically express the state of one or more key attributes of the system, or some guarantee about the state of the class owning the operation.

Figure 2-15 shows example postconditions linked to an operation.

Figure 2-15. Postconditions for operations


2.3.1.3. Body conditions

An operation may have a bodyCondition that constrains the return value. The bodyCondition is separate from the postcondition because the bodyCondition may be replaced by methods of subclasses of the owning class. (See "Generalization" for more information on subclasses.) For example, a class named Window may specify a body condition for a method named getSize( ) that requires the length and width of a window be nonzero. A subclass named SquareWindow may provide its own body condition stating that the width must equal the height. The bodyCondition is similar to the pre- and postconditions in that the constraint may be expressed in natural language or in OCL. See "Constraints" for more information. Figure 2-16 shows an example of a bodyCondition on an operation.

Figure 2-16. Body conditions for operations


2.3.1.4. Query operations

An operation may be declared as a query operation if the implementation of the operation doesn't modify the owning class in any way. In practice, modelers often use the query property to indicate a method that doesn't change any meaningful attribute of an object. For example, there may be internal cache attributes that are updated as a result of a query. The important thing is that the state of the system, from an external perspective, isn't changed by the query method; there can be no side effects to calling the method.

You indicate a query method by placing the query constraint after the operation signature. For example, an operation named getAge( ) that simply returns an integer without changing any internal value of the owning class would be considered a query method. In C++, this typically maps to a const method. Figure 2-17 shows several query methods on a class.

Figure 2-17. Example query operations


2.3.1.5. Exceptions

While they're technically not constraints, you may express exceptions thrown by an operation using similar notation. Exceptions are typically other classes (often stereotyped with the keyword «exception», though this is simply by convention) that are thrown by an operation in the event of an error. You can list thrown exceptions in a note attached to an operation using a dashed line. Figure 2-18 shows an example of an operation that throws several exceptions.

Figure 2-18. A method that throws several exceptions


2.3.2. Static Operations

Operations typically specify behavior for an instance of a class. However, UML allows for an operation to specify behavior for the class itself. These operations are called static operations and are invoked directly on the class, not on an instance. Static operations are frequently used as utility operations that don't need to use the attributes of the owning class. UML doesn't formally discuss the notation of these operations, but it is typical to see them represented with the same convention as static attributes. You indicate an operation is static by underlining the operation signature. Figure 2-19 shows an example of a static operation.

Figure 2-19. A class with a static operation





UML 2.0 in a Nutshell
UML 2.0 in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596007957
EAN: 2147483647
Year: 2005
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net