Z.J
Z.J

Reputation: 349

Should I model the class relationship between the concrete classes or the abstract classes?

In my UML class diagram, I have represented the composition relationship between UserModule and AddUser as well as between UserModule and ListUser at the abstract level, i.e., between the abstract classes AbstractModule and AbstractFunction. Theoretically, it would also be possible to model the composition directly between UserModule and AddUser or UserModule and ListUser. I would like to know whether this makes a semantic difference or if it is simply a matter of preference.enter image description here

Upvotes: 2

Views: 71

Answers (3)

Jim L.
Jim L.

Reputation: 6529

If you only have associations at the high level, then how will anyone know which function types operate on which domain types? The words encoded into the type names are only hints for humans who understand that natural language. The meaning is moved from the model into natural language, which can be slippery and misleading.

If you have at least mandatory minimum-cardinality redefinitions at the lower levels, then your model provides some meaning.

Yes, there is a “semantic difference” between these options.

Upvotes: 0

Christophe
Christophe

Reputation: 73530

The specialisations inherit the associations of their generalization.

This means that UserModule inherits the associations with AbstractFunctions and DomainObject and the related functions and domainObject properties (owned association end)

However, this design does not guarantee that the inherited associations would be with AbstractUserFunctions or User domain objects.

If you want this covariance guarantee, you would need to show associations (including composite aggregation) directly between the lower level classes. To avoid that these are interpreted as additional associations on top of those inherited you need to use one of the three following techniques:

  • redefinition,
  • subsetting, or
  • specialisation between associations (yes, this really exists),

You may look at how this can be done in this other SO question. Alternatively, you may have a look at this brilliant in-depth academic paper.

Upvotes: 1

nik0x1
nik0x1

Reputation: 1461

In your diagram you have a composition between AbstractModule and AbstractFunction, and since UserModule inherits AbstractModule, there is a corresponding relationship between UserModule and AbstractFunction. This connection is expressed in your case by the functions: List<AbstractFunction> attribute.

If you were to remove the connection between AbstractModule and AbstractFunction and make a connection from UserModule to AddUser, you would thereby define an attribute addFunctions: List<AddUser> that could store AddUser in its list, but not ListUser.

If you had also drawn a connection from UserModule to ListUser, then you would have defined another attribute listFunctions: List<ListUser> that could store ListUser in its list, but not AddUser.


Thus, by replacing one composition relationship with two, you would effectively be replacing one List<AbstractFunction> attribute with two other attributes of the List<AddUser> and List<ListUser> types.

Upvotes: 0

Related Questions