Constraints

A constraint is a Boolean condition bracketed by curly braces:

{student.gpa < 2.0} Constraints may be informal or formal. OCL (Object Constraint Language) is the official language for expressing constraints. In Rose, constraints may be placed in notes that are anchored to elements. Notes may also contain comments.

Reified Associations

Reification means the same thing as objectification or object-orientation. It is the practice of representing abstractions such as ideas, events, and relationships as objects (instead of functions or relationships, say).

Sometimes links between objects have attributes and need to be persistent (i.e., we need to be able to store them in files and databases). In these situations it makes sense to turn links into objects and associations into classes. We call such classes reified associations. Let's call instances of reified associations link objects.

For example, purchasing stock is a relationship between a person and a company:

In C++:

class Company
{
    set<Person*> owners;
    // etc.
};

class Person
{
    set<Company*> holdings;
    // etc.
};

But stock purchases, i.e., links or instances of the Purchases relationship, have attributes such as number of shares purchased, date, and price per share. It might be important to keep a record of these purchases. For example, Stock Watch and the Federal trade Commission watch purchasing patterns to try to detect insider trading.

The solution is to explicitly represent purchases as link objects instantiating a Purchases reified association:

In C++:

class Purchases
{
    Date date;
    unsigned int quantity;
    Money cost;
    Company* holding; // role A
    Person* owner; // role B
    // etc.
};

class Company
{
    set<BuyShares*> owners;
    // etc.
};

class Person
{
    set<BuyShares*> holdings;
    // etc.
};

Association Classes

Association classes are reified associations with an additional constraint. For example, a job is a relationship between a company and a person:

In C++ we might represent Job links as pointers:

class Company
{
    set<Person*> employees;
    // etc.
};

class Person
{
    Company* employer;
    // etc.
};

Some people have several jobs, but with different employers. For example, at night Earl is a bouncer at Club 42, where he earns $10/hr and his boss is the club's bar tender. In the day he is a programmer for MacroSoft, where he earns $5/hr and his boss is a MacroSoft division manager. Where can we store Earl's salary and boss information?

To solve this problem we can reify the Job association. Now Earl's bouncer job and programmer job are link objects: instances of a Job class. Each instance encapsulates a salary, an employer link, and an employee link. We can represent the Boss relationship as a Job self-association. Here is the UML notation:

In C++:

class Job
{
    Company* employer; // role A
    Person* employee; // role B
    Job* boss;
    set<Job*> workers;
    Money salary;
    // etc.
};

class Company
{
    set<Job*> jobs;
    // etc.
};

class Person
{
    set<Job*> jobs;
    // etc.
};

We can represent Earl's two jobs as two link objects that instantiate the Job association class. The link object representing Earl's bouncer job encapsulates a $10/hr salary and two role links: the employer link to a Company object representing Club 42, and the employee link to a Person object representing Earl. Here's an object diagram:

Although the Job class is a reified association similar to the Purchases class, there is an important difference: The same person can purchase stock from the same company many times, resulting in many Purchase objects. However, the same person can't have many jobs with the same company. In other words, two Job objects can't have the same employer and employee roles, but two Purchase objects can have the same holding and owner roles.

Follow this link to a mathematical example that some people may find helpful.