umlocl

How do I find a UML object if I only know the value of one of its attributes in OCL?


I have a UML class Student that has an attribute id. I want to write a query in OCL to find a particular Student by only knowing its id. Should I use allInstances()? Or derive? I'm not very familiar with OCL.


Solution

  • Usually OCL is used to express some constraints on an UML model, in relation to a given class instance (context or self) and you’ll start navigating from a specific instance.

    But OCL was developed as a formal specification language that can be used to specify more than only constraints, and in particular queries as explained in section 7.1. of the OCL specifications.

    If you want to express something regarding all the possible instances of a class MyClass, you would then start your clause with:

    MyClass.allInstances()  
    

    Wich is a set containing all the instances of the given class. Typically, you would then operate on this set to further specify some model features.

    For example, to express uniqueness of an id, you would write a Boolean clause on this set (based on example of section 7.5.10 of the OCL specs)

    MyClass.allInstances()->forAll(e1, e2 | e1 <> e2 implies e1.id <> e2.id)
    

    One of the operation you can perform on such set is to create a subset by selecting elements that match a certain condition, and this should answer your question:

    MyClass.allInstances()->select(c|c.id='...')
    

    Additional thoughts:

    OCL is an abstract language. Nothing is said on how this expression will be implemented. It could be a large inefficient iteration over an in-memory collection, or a very effective SQL query. OCL will help you to define what the result should be, but not how to really get it. So performance should not be your concern at this level of abstraction.

    Now, you didn’t tell the purpose of your OCL query. If it is to explain how database queries will be performed, you could see some advantages in separation of concerns: identify the relevant classes and reusable queries and enrich your model using the repository pattern: a repository is a (singleton) class MyClassRepository that acts as a container of all objects of a given MyClass in the database. You would then define operation for manipulating and querying the database. Typically, you’ll have a couple of getXxxx() operation like getById() that return one or a set of several instances. First it will make explicit what is to be implemented as a database functionality, second the new operations can be used to simplify some OCL expressions.