Operations are the processes that a class knows to carry out.

Operations most obviously correspond to the methods on a class. At the specification level, operations correspond to public methods on a type. Normally, you don't show those operations that simply manipulate attributes, because they can usually be inferred. You may need to indicate, however, whether a given attribute is read-only or frozen (that is, its value never changes). In the implementation model, you may want to show private and protected operations, as well.

The full UML syntax for operations is

visibility name (parameter-list) : return-type-expression {property-string}


  • visibility is + (public), # (protected), or - (private)

  • name is a string

  • parameter-list contains comma-separated parameters whose syntax is similar to that for attributes: direction name: type = default value. The only extra element is direction, which is used to show whether the parameter is used for input (in), output (out), or both ( inout). If there is no direction value, it's assumed to be in.

  • return-type-expression is a comma-separated list of return types. Most people use only one return type, but multiple return types are allowed.

  • property-string indicates property values that apply to the given operation

An example operation on account might be: + balanceOn (date: Date) : Money.

Within conceptual models, you shouldn't use operations to specify the interface of a class. Instead, use them to indicate the principal responsibilities of that class, perhaps using a couple of words summarizing a CRC responsibility (see Chapter 5).

I often find it useful to distinguish between operations that change the state of a class and those that don't. UML defines a query as an operation that gets a value from a class without changing the system state in other words, without side effects. You can mark such an operation with the constraint {query}. I refer to operations that do change state as modifiers.

I find it helpful to highlight queries. Queries can be executed in any order, but the sequence of modifiers is more important. It's my practice to avoid returning values from modifiers, in order to keep them separate.

Other terms you sometimes see are getting methods and setting methods. A getting method returns a value from a field (and does nothing else). A setting method puts a value into a field (and does nothing else). From the outside, a client should not be able to tell whether a query is a getting method or if a modifier is a setting method. Knowledge of getting and setting methods is entirely internal to the class.

Another distinction is between operation and method. An operation is something that is invoked on an object (the procedure call), whereas a method is the body of procedure. The two are different when you have polymorphism. If you have a supertype with three subtypes, each of which overrides the supertype's "foo" operation, you have one operation and four methods that implement it.

People usually use operation and method interchangeably, but there are times when it is useful to be precise about the difference. Sometimes, people distinguish them by using the terms method call or method declaration (for operation) and method body.

Languages have their own naming conventions. In C++, operations are called member functions, whereas Smalltalk calls operations methods. C++ also uses the term members of a class to mean a class's operations and methods. UML uses the term feature to mean either an attribute or an operation.