You can use Derivation Expressions in MDriven Designer to override an inherited derived attribute or association end when each subclass needs its own OCL expression.
When to override a derivation
A derivation defines the value of a derived attribute or a derived association end. A derived member is calculated from an expression rather than stored as an independently maintained value.
When a class inherits a derived member, its subclasses inherit that derivation. Override the derivation when the inherited member has the same meaning and type in every subclass, but the route to the value differs by subclass.
For example, let these classes exist:
- Class1 is an abstract base class.
- Class2 and Class3 inherit from Class1.
- Class4 is the common target type.
- Class5 and Class6 inherit from Class4.
- Class3 has an association to Class5.
- Class2 has an association to Class6.
Create one derived association end, Class4Derived, on Class1. Its type is Class4. Code that works with Class1 can then navigate Class4Derived without needing to know whether the actual object is Class2 or Class3.
| Runtime object type | Subclass-specific association | Override for Class4Derived
|
|---|---|---|
| Class3 | Class5
|
ocl: self.Class5
|
| Class2 | Class6
|
ocl: self.Class6
|
Class5 and Class6 can be returned from the derived association because both are subclasses of Class4.
Create the common derived member
- On Class1, create the attribute or association end that all subclasses will expose. In this example, create the association end Class4Derived with Class4 as its type.
- Mark the member as derived and enter a derivation expression.
- If Class1 is abstract and the member is only meaningful in subclasses, use
Class4.nullvalueas the base implementation. This is a placeholder; it is not used for an instance of an abstract Class1. - Ensure that Class2 and Class3 inherit the derived member from Class1.
Do not use a placeholder expression when instances of the base class can exist and callers can read the derived member. In that case, the base expression must return a valid value for Class1 instances.
Override the derivation in each subclass
- Select Class3 in MDriven Designer.
- Open Derivation Expressions.
- Find the inherited expression for Class4Derived.
- Replace the inherited placeholder with
ocl: self.Class5. - Select Class2.
- Open Derivation Expressions and find Class4Derived.
- Replace its inherited placeholder with
ocl: self.Class6. - Save the model and check that each expression is valid in its subclass context.
The overrides replace the dummy base implementation only for the relevant subclasses. The derived association remains one common member, typed as Class4, while each subclass supplies the appropriate path.
Read the result through the base type
After the overrides, a consumer can use the same navigation from either subclass:
self.Class4Derived
For a Class3 object, the expression resolves through self.Class5. For a Class2 object, it resolves through self.Class6. The caller sees a Class4 result in both cases.
Check the model before you finish
- The derived member must be marked as derived. An OCL expression alone does not make an attribute or association derived.
- Each overriding expression must return the type declared by the inherited member. In the example, both Class5 and Class6 conform to Class4.
- Use the exact association-end names from your model.
self.Class5andself.Class6are examples, not required names. - OCL expressions are queries and must not have side effects. See Documentation:OCL Expressions.
- If you need a value to be split into separate stored parts during an update, that is reverse derivation, not an override of a read derivation. See Documentation:Reverse Derivation.
Related derivation behavior
Derived attributes and derived associations can be reused by other derivations, which helps you keep definitions small. For example, a derived total can use another derived value instead of repeating its full calculation. See Derived attributes & associations.
A derivation is model-level logic. When you query persistent storage, do not assume the database contains a physical column or association for the derived member. MDriven can expand derivations in supported persistent-storage query scenarios; see Documentation:Derivation is not available in the database.
