OCL relies on the types (classes, datatypes, and so on) defined in a UML model; thus, using OCL includes the use of (at least some aspects of) UML. Any model in which OCL plays a part consists of some UML diagrams and a series of OCL expressions. Often, only the class diagram is used, but other diagrams may be included in the specification. A model must be an integrated, consistent entity. In a model, it must be crystal-clear how entities used in one diagram relate to entities in other diagrams. The same holds for the relationship between expressions that are not linked to diagrams, as OCL expressions often are, and entities in the diagrams. You can view this relationship in two ways. First, expressions linked to specific entities may have only specific functions. For instance, an expression defining a new attribute may only be attached to a class, interface, or datatype. Second, the UML model entity to which an expression is linked defines which other model entities are visible and can be referenced. For instance, in an expression attached to a class, all attributes, associations, and query operations of that class may be used. The link between an entity in a UML diagram and an OCL expression is called the context definition of that OCL expression. 6.1.1 The Context of an OCL ExpressionThe context definition specifies the model entity for which the OCL expression is defined. Usually, this is a class, interface, datatype, or component. Sometimes it is an operation, and only rarely it is an instance. It is always a specific element defined in a UML diagram. This element is called the context of the expression. OCL expressions can be incorporated in the model directly in the diagrams, but they may also be provided in a separate text file. Both cases include a context definition. In the diagram, the context definition is shown by a dotted line that links the model element and the OCL expression. In Figure 6-1, five expressions and their contexts are shown. Figure 6-1. OCL expressions and their context
When the OCL expression is given in a separate text file, the context definition is given in a textual format. It is denoted by the keyword context followed by the name of the type, as shown in the following example invariant: context Customer inv : name = 'Edward' In addition to the context, it is important to know the contextual type of an expression. The contextual type is the type of the object for which the expression will be evaluated. With type, we mean either a class, an interface, a datatype, or a component (in terms of the UML standard, a Classifier ). Note that a package is not instantiable ; therefore, it is not a type. When the context itself is a type, the context is equal to the contextual type. When the context is an operation, attribute, or association end, the contextual type is the type for which that feature has been defined. When the OCL expression is connected to an instance in a diagram, the contextual type is the type of that instance. OCL expressions are evaluated for a single object. This is always an instance of the contextual type. To distinguish between the context and the instance for which the expression is evaluated, the latter is called the contextual instance . OCL expressions can have many different functions, depending on the context of the expression. For instance, when the context is an attribute, the expression may represent an initial value or a derivation rule, but when the context is a class, the expression will never represent an initial value (an initial instance). The remaining sections in this chapter describe the ways in which an OCL expression may be used when connected to various contexts. 6.1.2 The self KeywordSometimes it is necessary to refer explicitly to the contextual instance. The keyword self is used for this purpose. Whenever the reference to the contextual instance is obvious, the use of the keyword self is optional. Thus, the previous invariant can be written as follows : context Customer inv : self.name = 'Edward' The R&L model from Chapter 2 includes an invariant in which the reference to self is not optional: context Membership inv : participants.cards.Membership.includes( self ) 6.1.3 More Than One Expression to a ContextOften, more than one invariant, or pre- or postcondition, or other type of expression applies to the same context. These can be combined to follow one context definition statement. Because all invariants need to be true for an instance of the class, the invariants are conceptually connected by the Boolean and operation. The same holds for sets of pre- and postconditions. Therefore, the following two examples have exactly the same meaning: context Customer inv : self.name = 'Edward' inv : self.title = 'Mr.' context Customer inv : self.name = 'Edward' and self.title = 'Mr.' The following two sets of pre- and postconditions have the same meaning as well: context LoyaltyProgram::addService(p: ProgramPartner, l: ServiceLevel, s: Service) pre : partners->includes( p ) pre : levels->includes( l ) post : partners.deliveredServices->includes( s ) post : levels.availableServices->includes( s ) context LoyaltyProgram::addService(p: ProgramPartner, l: ServiceLevel, s: Service) pre : partners->includes( p ) and levels->includes( l ) post : partners.deliveredServices->includes( s ) and levels.availableServices->includes( s ) |