I found the following class diagram through google(from researchgate) and I am confused with the relationship between the Account class and the Client class. AFAIK, this way the diagram shows that multiple clients can be related to one account. But shouldn't it be the other way around? I can create multiple accounts in a bank and be their owner. According to me the cardinality should be 0..n on the Account class and 1 on the Client class because one owner can have multiple accounts. Am I missing something?
Related
I am trying to show here that Admin is a sub-class of User which is shown through the open triangle relationship connection. Is this enough to show that the sub-class relies on the main parent class to exist or would I then need to further apply composition? I have shown my example below. I am super confused regarding this. I feel it's enough to show it through the specialization arrow but I am not sure.
Is this enough to show that the sub-class relies on the main parent class to exist or would I then need to further apply composition?
Because of the generalization an Admin is a User, so if there is no User at all (User.allInstances()->size() = 0) then there is no Admin too. But of course you can have User(s) without having Admin.
If you just want to say that nothing more than the generalization is necessary.
But if you want to indicates an Admin is a User and there is 1 and only 1 admin you can do :
As you can see admin is a property of the class User (isStatic is true) because it is written underlined, no need to have it for all instances (including the admin(s)).
An other way to say the same without using an additional relation is :
Of course if you want to say there is at least one admin and not exactly one just use the multiplicity 1..* in the first solution or modify the constraint to have {allInstances()->size() >= 1} in the second solution.
I'd like to add another view to Bruno's excellent and accurate answer regarding generalization.
Yes, it is indeed sufficient to make Admin a specializatrion of User: this means that Admin is a User. It also means that Admin inherits User's non-private properties and operations (i.e. AuthenticateUser()). Finally it means that an instance a of Admin is also an instance of User and has hence a username and a password, although these are visible only to User instances. Unfortunately, once an object created as Admin, it will always stay an Admin.
Your hesitation about composition is therefore perfectly understandable: it is often advised to prefer composition over inheritance. You could perfectly imagine to have a User that has an Admin role, without Admin inheriting from User. But this is a radically different design. And in this specific case, it would be strange, if there wouldn't be other roles as well.
Last but not the least, it's worth to mention de decorator pattern that may combine inheritance with aggregation (instead of composition): In this design, you would make Admin a decorator of User: it extends the reponsibilities of the User with Admin responsibilities (i.e. with additional operations). But this can be done at runtime: you can create a User, add an Admin responsibility, or remove the Admin responsibility. THis is much more dynamic.
Example:
I have two bounded contexts Exams and Courses. The Exams context has a Student entity that has information about the students to take an exam. And the Courses context has a teachers entity that contains information about the teacher teaching a course.
I also have an AuthService (purely CRUD), that is used for Authentication and Authorisation of users. The AuthService has an Accounts entity, which contains information like accounts user's name, address, phone number e.t.c.
Bringing them all together, The Student and the Teacher both have Accounts hence their information is already available.
I have a couple of question about this.
Is it anti-pattern in DDD to store the AccountId in the Student and Teachers Entity? If it isn't anti-pattern at what point is it ok to collect students account information using the AccountId, In repository or in the API controller, or should we use RPC/API calls.
Is it okay to copy the details needed from the Account entity into a Student or Teacher Entity?
I assume the AuthService is in its designated bounded context for authentication and, Accounts is in that same bounded context too.
Here are my answers:
Is it anti-pattern in DDD to store the AccountId in the Student and
Teachers Entity?
You can store AccountId in Student and Teachers entities. This is not an anti-pattern but rather opposite - this is how different aggregates refer to each other, by keeping the Id of the other aggregates.
If it isn't anti-pattern at what point is it ok to
collect students account information using the AccountId, In
repository or in the API controller, or should we use RPC/API calls.
I don't understand which repository you mean exactly, for Account, Student, or Teacher? Each aggregate root has its own repository and that repository is responsible for storing those aggregates only. It does not know or query other aggregates. If you need to query other bounded contexts, do that from the application layer - if the operation that does this is not a domain concern. If it's a domain concern, then do this in the domain layer by representing another bounded context as a domain service (interface). RPC/API is an implementation detail for the inter-bonded context calls and you can use either way to query another bounded context, as long as the implementation details don't leak into the domain layers.
Is it okay to copy the details needed from the Account entity into a Student or Teacher Entity?
That is also okay. You do that to achieve higher availability for the price of eventual consistency. In such a case, the bounded context/entity that holds information from another one acknowledges that the copy of the data can go stale but that is acceptable by the business terms.
Let me know if any questions. I am a long-run DDD practitioner.
I think you are in the wrong way. Something that is related to Authentication should not to be in the domain layer. Student and Teacher are entity, but Account in AuthService is not entity. As far as I see, you would like to add a new Student or Teacher by using some information that come from Account, but for doing that you should pass this information by fetching User Account info and pass them to Student or Teacher class to instantiate a new object.
For your second question, depends on our business, you could have same properties. DDD just emphasize that you should use ubiquitous language for naming entities and methods and it doesn't matter you use same properties.
I want to design a class diagram of a simple login operation. Use case is:
User enters id and pin
System checks login info.
So, I decided to create a controller for the user (UserHandler) and a user class (User). UserHandler takes id and pin and checks that they are valid with a method ( isUserValid() ).
In my opinion, a class should not include all database records for only one of them. I mean there should not be a list of users to check whether login info is correct or not. This is a simple operation with just a requirement of connecting to database.
My question is how can I show that isUserValid() method is connecting to the database? Is there a need of showing this connection?
Or should I create a userList in UserHandler and keep all the users in that list?
Any help will be very appriciated.
You would create an Authorization class that takes a user name/password to authorize. This Authorization class will look into the users database. You could model this as association with multiplicity.
I am working on a multi-tenant cloud application and considering using E-mail addresses/passwords for general login credentials. However, I may have the same user (same E-mail address) associated with multiple tenants based on the planned sales model for this application. For example, multiple departments in the same company might be separate tenants, or separate companies must be separate tenants. In either case the same user (with same E-mail address) might be a user of these different tenants.
What are possible design strategies for handling such situation?
One approach I am considering is separating creation and update of the user E-mail credentials from the tenants. In this approach a tenant could invite a user (by sending an E-mail) and the user can use the same login credentials for access to all tenants, merely switching between tenants as desired.
What I have typically seen in current web applications is that the user has to have separate E-mail addresses for each tenants, which seems a burden for the user.
Thanks.
Assuming your question is about the technical design (and not the user experience), this is a pretty straight forward solution. Create the users independently from the tenants, and allow for a many to many relationship that represents the "has access to" phrase.
Depending on your chosen backend, there are different manifestations of the design pattern:
RDBMS: Create a user table, tenant table and a user_has_access_to relationship table
Directory Server (LDAP): Place the users into a single OU within the directory, and create the tenants as group objects. The users could then have the memberOf attribute set for each tenant they are able to access.
The LDAP option above has the limitation of overloading the group entity. If you are comfortable enough with LDAP schema definitions, you could just as easily create a tenant object and add a hasAccessToTenant attribute to your user object. Taking this approach would allow you to use groups to represent actual user groups (as the object type was intended to be used).
A more advanced design option would include the creation of a "has access to" relationship between tenants. Adding this, along with the user to tenant relationship, would open up more advanced relationship modeling. For example: a tenant with departments or divisions, allowing users with permission to the top level tenant to automatically "have access to" the divisions.
Using the same credential across namespaces in multi-tenant applications is technically possible. For example, when a user logs in, the application can check across the namespaces and determine which all namespaces he belongs to. There is a possibility, the user may have different levels of authorizations against these namespaces. This is also implementable.
The real problem is the experience the application can offer to such users. They will require a special landing page which will allow them to chose between the namespaces. The chosen namespace should be made quasi-permanent during the session, that is, until the user logs out. ( I am trying to implement this in a new application on GAE/Python27 )
Other possibilities are restricting the user to a single namespace and asking the user to use different credentials against each namespace, which seems to be the prevailing practice.
My application domain has Users. It also has Organisations. Users can create Organisations.
My question is On which controller should I put the CreateOrganisations method? Does it belong on the UserController? Or does it belong on the OrganisationController? And how do I make that decision?
In any case, I plan to have an Add method on the Organisation model.
Any thoughts?
It belongs on the OrganizationController.
The Organization controller should be managing any creation/change to the organization model. The user should have no knowledge on how or what is involved in creating an organization. If you give them the ability to create organizations you are coupling logic. You make this decision because you have both a User and a Organization Controller.
If your user/organization don't really justify existence, aka they aren't really controlling much then merge them into one.
If both classes exist I vote for organization.
Like you said, a User can create an organization, so unless the organization doesn't tracks the owner (unlikely), you should have the CreateOrganization method delegated onto the user. A basic idea I can think of would be like:
User: Creates organizations by calling OrganizationRepository::Add( OwnerId )
Organizations: Can only be created given the id of the owner.
If (and only if) you don't need to track the creator of organizations, then the idea of placing an Add method directly on the organization without requiring anything else looks fine.
Hope I can help!
David