UML Domain model - how to model multiple roles of association between two entities?
Asked Answered
S

3

5

Suppose there is a scenario of Users having Tasks. Each User can either be a Watcher or Worker of a Task.

Furthermore, a Worker can file the hours he has worked on a given Task.

Would the following diagram be correct? I have looked around at domain models and I have not seen one with the two associations (works on, watches). Is it acceptable?

enter image description here

EDIT: What about this scenario? An User can make an Offer to another user. A possible way of modelling it is shown on the following diagram.

However, in that diagram it would seem possible for a user to make the offer to himself. Is it possible to model some constraints in, or is this handled further down the development line?

enter image description here

Sufficient answered 19/3, 2016 at 10:58 Comment(3)
Sure. There are no UML police to flag you down for being "unacceptable". The real question is: Does this work when you code it? UML doesn't matter; only code does.Biracial
I guess I am not sure how much information this model is supposed to convey. Can any constraints be shown here? (see edited question) I know there is no UML police, but this is a part of a school project, so there will be the next best thing to it when it's evaluated - the professors :| That's why I want to have it as formally correct as possibleSufficient
People who do this for a living do the best they can to think things through before they begin, but it's more common to learn and adjust when you code.Biracial
G
6

It is in principle correct, this is how you model multiple relationships between two classes.

As for the constraints, UML makes use of OCL (Object Constraint Language), so you can say that the associations are exclusive (xor - exclusive or).

Also note that it is generally a good idea to name the end roles of the associations.

enter image description here

Regarding one of the comments saying

There are no UML police to flag you down for being "unacceptable".

It is like saying: there's no code police to flag you down for writing shitty code.

You create diagrams to convey information (for school project anyway), if you diverge from standards or best practices you make it harder for other people to understand your diagrams.

And just like there are linters (jslint, ...) that check your code for common problems, for models there are model validations that do the same thing.

Also models, just like code, aren't set in stone so don't be afraid to modify them when you find a better way to express your domain.

Update

As Jim aptly pointed out, you usually do stuff not as a User (or Person), but as a Role. E.g. when you are student and you are filling a form, nobody cares that you are human, but that you are a Student. Typically a Person will also have several different roles (you could be a Student and a TA, a Professor, etc.)

Separating it in this way makes the domain much clearer as you are concerned only with the Roles, and not the people implementing them.

enter image description here

Grindstone answered 19/3, 2016 at 12:14 Comment(4)
You can also use an association class in the first case. Saves a single connector line ;-)Merrilee
@Peter: your answer seems the best to me. However, I would add one detail: since this is supposed to be a domain model, I would expect to see terms from the problem domain, like Watcher and Worker, not User. Moreover, I would model this as a Person playing the role of Watcher or Worker with respect to a Task. The idea of a User is not part of the problem domain, it is part of the solution domain.Schoenfeld
@JimL. I have several different roles for each user. Do you think there should be a separate entity for each of them? There are Watchers/Workers in relation to Tasks, then there are Members/Managers/Admins in relation to Groups etc. - but in reality, it is still the same user. Only when looking at a particular instance of Task or Group does he "become" the role.Sufficient
@MartinMelka: I added an answer with a diagram. Please let me know whether or not you find it helpful.Schoenfeld
E
3

On the first model, there's not much to add after Peter's excellent and very interesting answer.

However your second diagram (in the edit section) does seem to give a true and fair view of the narative. From the strict 1 to 1 relationships, I'd understand that every user makes exactly one offer to one other user, and every user receives exactly one offer from another user:

  • "A user can make an offer to another user" implies a cardinality of 0..1 or *, not 1.
  • From this we understand implicitly that not all users need to receive an offer, i.e. also a cardinality of 0..1 or *
  • This can be debated, but "an offer" doesn't in my opinion mean at "at most one offer", so the upper bounds of cardinality shouldn't be * and not 1 to show that every user may make several offers and receive several offers.

enter image description here

As you can see, you can add constraints to the schema to increase expressivity. This is done in an annotation between { } . But you can choose the most suitable syntax. Here an example with the full expressivity of natural language (as suggested by Martin Fowler in his "UML distilled") but you can of course use the more formal OCL, making it {self.offerer<>self.offeree}.

Erysipeloid answered 19/3, 2016 at 15:10 Comment(1)
Yes, thank you. The 1 to 1 cardinality was an oversight. The constraints is what I was looking for.Sufficient
S
2

I see @Peter updated his answer before I could post this answer, but I will post this anyway to show you some other tricks.

In general, it is perfectly valid to have multiple associations between the same two classes. However, I don't think it's a good idea here.

You say you want to build a [problem] domain model. I'm glad to hear that! A problem domain model is very important, as I explain in the last paragraph here. One thing to point out is that you want to build a durable model that transcends a system you can conceive. In the problem domain, there is no "User". There are, however, Roles that People play. For example, you mentioned Watcher and Worker. Hopefully these are concepts your customer already has in the "meat world".

In the model you posted, you have no place to hang the hours worked or progress made. You might try an exercise. If you had no computer, how would your customer track these things? They often have (or had) a way, and it was probably pretty optimal for a manual system.

Here is how I would model my understanding of your problem domain:

enter image description here

Some things to note:

  • A Person plays any number of Roles.
  • A Role is with respect to exactly one Task and one Person. A Watcher watches exactly one Task, a Worker is assigned to exactly one Task, and any kind of Role is played by exactly one Person.
  • A Role is abstract, and its subclasses are {complete}, meaning there can be no valid instance of a Role without also being an instance of a subclass.
  • A Task is watched by any number of Watchers and may be assigned to one Worker at a time. There is a constraint saying {person is not a watcher}. (You can show the OCL for that, but few people will understand it.)
  • I have added a Progress concept as a way of logging progress on a Task. A Worker makes Progress on one Task. Each bit of Progress has a Description and a Duration. Note that I have not committed to any computational way of representing a Description or a Duration. The designer of a system for this will be free to derive a Duration from start and end times, or ask the user to self-report.
Schoenfeld answered 20/3, 2016 at 14:19 Comment(1)
Thank you, this is a well elaborated example!Sufficient

© 2022 - 2024 — McMap. All rights reserved.