I want to model a simple system using a Class Diagram:
- I have 3 possible classes:
Company
,Employee
,Manager
. - The
Company
must have 20Employees
(aggregation?). - The
Company
must have 1Manager
(aggregation?). - A
Manager
is an Employee (generalization?). - Each
Employee
can only be in 1Company
.
In other words, I want to limit this system to have 20 Employees
, 1 of which must be a Manager
. However ONLY 1 can be a Manager
. This would make it so that there are 19 Employees
and 1 Manager
objects at all times.
I have the setup in my head of how I want this system to work, but I can't get the model quite right. This is what I got:
I feel like I am very close, but my issue is that although the Company
1 to 1 relationship to the Manager
seems correct, the 1 to 19 to the Employee
seems off. Since a Manager
is an Employee
, I have no way of limiting how many of those 19 Employees
are Managers
. I am trying to do this without splitting Employees
up into Non-Manager
and Manager
classes.
Am I on the right track? Is there something I am missing? Or is it clear enough that 19 MUST be Employee objects and 1 MUST be Manager object?
The problem
Your model has a weakness: a
Manager
of one Company could beEmployee
of another, because nothing in your model says that the employment relationship with theCompany
is the same for both classes.Why? If you apply the UML generalization semantics:
Employee
has an association withCompany
,Manager
is a specialization ofEmployee
, and therefore inherits all its properties, operations and associations, including the association withCompany
.Manager
has in addition its own association with theCompany
. So it has two distinct associations: the inherited one and its own one.Potential solutions
It would be helpful to label the ends of the association, e.g.
employer
/employee
andcompany
/manager
:The simplest solution could be to remove the association between
Manager
andCompany
, since it is inherited. But there is no easy way to tell that there must be aManager
among theemployees
. Moreover, there wouldn't be an easy way to find theManager
of aCompany
. So this solution does not appear appropriate.Another solution would be to add a constraint that specifies that for the
Manager
,manager.company
is the same thanemployee.employer
. Since aManager
manages one and only onecompany
, no other manager could by deduction exist among theemployees
. But this sounds somewhat artificial.The best solution in my view is therefore to keep both associations but use UML smeantics to explain that
company {subsets employer}
andmanager {subsets employee}
Be aware that this solution requires 20 employees, since it makes clear that the manager is one amont the 20.If you're interested to know more about subsetting, I advise you this artile about redefinition, specialization and subsetting of associations, which could also inspire you other variants.
Minor remarks
The aggregation are fine. However, aggregation is a modelling placebo since the UML specs clearly say page 110:
Therefore, I'd suggest to avoid them when possible. You could therefore as well use normal UML associations. Especially for the manager where there is only one.
Another remark made by qwerty_so in the comments is that the
+
should be removed in+has
: The+
is about public visibility. It’s not the association itself that is public or private, but the association end (e.g.employer
andemployee
in my proposal).