2

Generally in the Enterprise Applications like ERP or ERM, CRM, BP etc. we see two things a lot, one of them is Role and the other one is User. What happens is that in the real world we have some persons as the Audiences of the Organization and also we have some roles that each person do his duty as that role. Actually each person has his own information in his file, dependent on the role that he has. Notice that one person can has more than one role.

The question is that How can we model this topic as the OO (Object Oriented) viewpoint?

One way is that we have an Inheritance Hierarchy of Users which each one has his own data and his own behaviors (for example in one clinic we have doctor, patient and Secretary that all of them are derived of the user.) User has list of roles. In this case roles are more likely to Enum and does not have any behavior and the main use of them is Access Control.

The problem of this method is that if a real person wants to have different roles and this issue is completely dynamic, modeling of this wouldn’t be clear.

Second method is that we have one user and an Inheritance Hierarchy of roles that each role has his own duty. We assign this roles to the users. Actually we see the roles in the program and the main operant for us are the roles.

The problem of this method is that for some roles it is necessary that users have other personal information (for example about the doctor the field of study should be defined.) and it is not clear that where we should store these data.

The third method that is not obvious for us is a combination of the two method above.

1

Why don't you separate the concepts?

Have one bounded context to handle the user identity. This BC will have all data related to the person itself. This should answer "Who is that user?"

Have another BC to control the roles which each user have. This BC will be responsible for answering "Is this user allowed to do that?"

And a 3rd BC for the operations that you need the entity to do. Now you have 3 models for the same concept, but in different contexts. This may sound really complicated, but each BC has a clear definition of what the entity is (different attributes) and what it can do (its responsibilities)

What is dangerous about your approach is that an entity will have many responsibilities. This violates the Single Responsibility Principle and will go out of hands really fast once the applications grows significantly.

  • thanks for your response, but your solution is very complicated and it leads to highly redundancy of data so reduces maintainability, performance and increases cost. but the real problem of your solution is in 3rd BC we need to "who is that user" and "Is this user allowed to do that" because for each operations I need user data's, profile's and roles. in another words I think we cannot separate these concepts. – sorosh_sabz Feb 11 '15 at 21:12
0

One way is that we have an Inheritance Hierarchy of Users which each one has his own data and his own behaviors (for example in one clinic we have doctor, patient and Secretary that all of them are derived of the user.)

That's IMHO not a good approach. You have persons (IMHO a better term than "users"), and "doctor", "patient", and "secretary" are clearly roles of a person, because a person can be simultanously a doctor, a patient, and / or a secretary.

Second method is that we have one user

I would call it a person ...

and an Inheritance Hierarchy of roles

... yes if your roles are derived from a common "role" class. Now you can have a 1:n relationship between persons and roles.

... The problem of this method is that for some roles it is necessary that users have other personal information (for example about the doctor the field of study should be defined.) and it is not clear that where we should store these data.

This depends. At a first glance, a "field of study" is a personal qualification. You gain it independently of beeing a Doctor, maybe at a different point in time. So the natural solution seems to be a 1:n relationship between "person" and a qualification object (or a "Field of Study" object, if that is the only form of qualification you ever need to store).

If you really need that information exclusively for doctors, and only as long as the "Doctor" role is assigned to a specific person, then you can assign it to the Doctor object instead, but I would not recommend it. The functional dependency "each doctor needs to have a field of study" can be enforced by the surrounding application, as part of the role assignment process, it is not mandatory to make "Field of Study" an attribute of "Doctor" for that purpose.

EDIT: here is an example class diagram as a rough scetch, probably some details don't match your exact requirements, but I hope you get the general idea:

Person-Role example model

  • thanks for your response, but in your solution person dose not have any behavior and just have so many fields, that each role uses its person's data. this phenomenon smells in OO design. one object has fields and another object has behavior :(. – sorosh_sabz Feb 11 '15 at 20:41
  • when I need to know field of study for each doctor I have to store this data in one place. in another words I can say in OO paradigm: "doctor has member variable(field) that called field of study". – sorosh_sabz Feb 11 '15 at 20:49
  • 1
    @sorosh_sabz: do you want to follow your dogma, or do you want a solution which works? Pick your choice. – Doc Brown Feb 11 '15 at 20:52
  • I want to find the solution which has the most compatibility with OO principles. – sorosh_sabz Feb 11 '15 at 21:13
  • @sorosh_sabz: different people have different opinions about what good "OO principles" are. Maybe you got me wrong, but in my answer, I did not write anything about fields for a "Person" - just relationships to separate classes like Qualification or Role. A Person has no "behaviour" because you asked about the core modeling of users and roles, not how to implement use cases on top of that. ... – Doc Brown Feb 12 '15 at 7:09
0

Firstly, congratulations on recognising that inheritance is a poor choice in this situation. You are 100% correct. Changing the type of an entity at run-time is definitely code smell!

@Doc Brown's answer is getting to the heart of the matter, especially the comment about using Person rather than User, and allowing a 1:many between Person and roles.

What is missing here is the period for which the role is valid. For instance, a doctor may also become a patient in middle age, and the patient role may be valid after he retires as a doctor. Similarly, a person may be an employee several times, and may be a manager for one or more periods. The take-out is that roles are time constrained, and as such require their own entity in the model.

I see you are concerned about complexity, and that is natural. My experience has been that if you get the data modelling 100% correct, then there is little complexity. The special cases that require tens of lines of code just disappear - the model reflects reality. For instance it will be able to answer quite complex queries like "what doctors are still on staff that were staff doctors during the Ebola epidemic in 2014?"

The guru in this modelling area is Peter Coad. I suggest http://www.step-10.com/SoftwareDesign/ModellingInColour/ as a suitable introduction to his ideas.

  • Indeed, you are correct, and I was actually aware of the possibility of modeling roles with an additional period of time. I left it out for the sake of simplicity and since the OP did not mention it as an explicit requirement. – Doc Brown Feb 12 '15 at 8:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.