Multiple association is the confluence of multiplicity and viewing association as bidirectional aggregation, representing the most general and expressive constructive class relationship. However, this flexibility has a price: it's also the most challenging to understand and program. Programmers implement simple (one whole and one part) aggregation with a pointer in the whole class and more complex aggregation (one whole and many parts) with multiple pointers. We can organize the multiple pointers as an array or an instance of a container class (e.g., a vector). Similarly, multiple associations allow both peers to associate with one or many instances of the opposite peer; programmers implement multiple associations with multiple pointers. The following figure illustrates the multiplicity syntax describing four possible organizations.
| (a) | (b) |
| (c) | (d) |
Association generally and multiplicity specifically challenge class developers when choosing which class to make responsible for managing the program's necessary data and operations. A few scenarios illustrate how the original problems help guide the selection. The scenarios build on the contractor and project classes, illustrating associations throughout the text. The examples begin by assuming that each problem requires the program to manage the contractor's pay rate and time worked and calculate the contractor's pay. The class designer's task is to determine which class is responsible for providing these features.
| Scenario | Description | UML |
|---|---|---|
| 1 | A homeowner hires a contractor to do a small home repair project. The contractor has a single client with a single project, and the client has a single contractor. The contractor sets the pay rate and monitors the time. In this case, the contractor class manages the data and operations. | |
| 2 | Alternatively, the client may advertise the project and its pay rate. Furthermore, the client may track the contractor's working time. In this case, the project manages the features. | |
| 3 | A homeowner hires a contractor to build a deck, a project requiring time for the concrete to set. A busy contractor has many ongoing projects to fill the waiting time. The pay rate and time allocated to each project vary, so the contractor is responsible for these features. | |
| 4 | I worked as a software engineer for a company that often hired contractors. The contractors worked on various projects with different rates of pay, and worked different amounts of time. In this case, the project manages the features. | |
| 5 | Specialized contractors may work on multiple projects simultaneously, dividing their time between them and charging each a different rate. A large company may have many specialized contractors, working various amounts of time at different rates. A UML class diagram can represent this scenario as a many-to-many association relationship, specified with an asterisk (the "many" operator) at each end of the association connector. However, the features controlling the contractor's pay do not "belong" to either class - they belong to the specific association between a contractor and a project. |
When we instantiate classes connected by aggregation or association, we simultaneously instantiate the connections between the objects. The UML refers to these connections as links. When a class design assigns responsibilities to the associations in a many-to-many relationship, we can manage the data and functions with a construct called a link class.
class link;
class contractor
{
private:
link* projects[25];
};
|
class contractors;
class project;
class link
{
private:
contractor* c;
project* p;
double rate;
double time;
public:
calc_pay() : double;
}; |
class link;
class project
{
private:
link* contractors[100];
};
|