In my system, an User can be member of a Team.
I got a domain model called Team which contains id, name, member_count and is_channel. So when I fetch teams in the repository I retrieve the Team domain model.
How would I model the relation between a User and a Team? Because when talking about the relation I don’t care about the member_count and is_channel from the Team model. I even have extra data in the relation which is a role_type.
Should I create a domain model for the relation called TeamScope or something? That contains id, user_id, team_id, role_type?
See my comments on your question regarding your use of terms (model, class, association). I'm assuming you are misusing them when I wrote my answer.
How would I model the relation between a User and a Team? Because when talking about the relation I don’t care about the member_count and is_channel from the Team model (sic). I even have extra data in the relation which is a role_type.
You could use an association class in your domain model to represent this.
Membership can capture the role_type, which really is linked to the association as you have figured out.
member_count is represented with a / at the start, indicating that you'll derive its value from the multiplicity (it's a count of the number of members associated with the team).
You tagged node.js in your question, so I'm going to point to how to implement association classes in Java (not exactly your case, but in Node.js it should be easy to apply).
You should almost definitely model a TeamMember object which contains both a link to the User, a link to the Team, and the role the user plays on that team.
Teams have a list of TeamMembers, Users have a list of TeamMembers. Teams have a MemberCount (not sure if this is static, or dynamic from the count of TeamMembers), and I have no idea what is_channel means...
Related
In many applications, I deal with users and finance companies (as an example) and I have long been struggling to model the relationship between the two according to Domain Driven Design principles.
In my system I can do the following:
Add a user to an existing finance company.
Add a finance company to an existing user.
I believe both are aggregate roots... Finance Company and User.
How do I model the relationship between the 2? Is it FinanceCompany.Users? or User.FinanceCompanies? Is it neither? Or am I missing knowledge of some key DDD concept(s)? The problem is if I choose one way over the other, the code is more understandable / clear from one aggregate root entry point, but not the other. Sometimes there are cases where it makes more sense to navigate to a Finance Company and add users to it, and other times there are cases where it makes more sense to navigate to a specific user and add finance companies to the user.
Is there some better way to approach this, maybe through repository methods? Is there some key concept I am not getting or understanding here? It doesn't feel right to assume the relationship between Finance Company and User belongs under either of the 2 ARs. When I store the relationship I have to store it in a table named FinanceCompanyUsers or UserFinanceCompanies, but it still doesn't seem clear.
Would I have code such as FinanceCompany.AddUser() and User.AddFinanceCompany()? or is there some completely different approach for relationships such as this?
You have already determined that both User and FinanceCompany are aggregates so each has its own life-cycle.
The problem with many domains is that we don't have a complete understanding of the relationships. As another example we can take an Order and a Product. Both are aggregates but would we have Order.AddProduct() or Product.AddOrder()? In this case it seems pretty obvious in that an Order contains a limited subset of Product entries whereas a Product may very well contain many orders and we are not really too interested in that relationship since it is a rather weak relationship. A Product can exist and be valid without any orders attached but an Order is pretty useless without at least one product entry. This means that the Order has an invariant imposed in terms of its OrderItem entries. In addition to this we have enough knowledge about this hackneyed example that we know we are going to need an associative entity (in relational theory speak) since we need additional information regarding the relationship and entering the fray would be our OrderItem table. Curiously I have not seen it called OrderProduct.
The guidance I would suggest is to pick the most appropriate side.
However, if no side is a true winner and both aggregates can exist without a relationship to the other in terms of an invariant perhaps the relationship itself is an aggregate as you have certainly alluded to. Perhaps it isn't only a UserFinanceCompany aggregate but perhaps there is a concept that is missing from the ubiquitous language that the domain experts refer to. Perhaps something like Auditor or some such that represents that relationship. This is akin to the OrderItem or OrderLine concept as opposed to OrderProduct.
I am trying to draw a conceptual class diagram. In my system, I have one person who can be performing 2 roles. One being "teacher" and other being "student". The same person could be a teacher in one instance and the same person could be a student in another instance. In such a situation, is it good to depict them as 2 separate classes (in my conceptual diagram)?
Please advise.
Thanks
Unless the person is teaching themself, don't get caught up in trying to show relationships that cross a use-case boundary. Validate the links for each scenario separately; just realize that not all connections will be used for every scenario.
People fill roles. Try
Person associated with EducationRole
EducationRole has subclasses of 'Student' and 'Teacher'
Here is a diagram.
They can change the role they play depending on the situation. If you need to show a person teaching themself then create a subclass of EducationRole named 'Autodiadact' which just means self-teacher.
A commenter asked about changing the role using a method and I'd like to include the answer here.
So, yes you could code the ability to change the role in a method but back up and ask the bigger question, why are we changing the role? A teacher is becoming a student or a student is becoming a teacher, either way the model as shown allows a Person to have many EducationRoles (which is what the asterisk denotes) at the same time so there isn't really a need to change the role but support a person with multiple possible roles.
In the conceptual model you are attempting to illustrate relationships between any valid state of the system, not necessarily how the change might be executed (using a method).
what factors determine navigability of a relation while modelling , canonincal example
Company m..n People. what should be the direction of navigability in this relation ??
This is a design decision. At the analysis level you usually model all associations as bidirectional associations but, later, when moving to the implementation phase you need to start thinking about how to transform associations into Java attributes (if implementing in Java) and here the navigation play an important role since you must decide whether you want to access people objects from company (attribute people in company), company objects from people objects (attribute company in people) or both (attributes in both classes but be careful with consistency issues)
It depends on your requirements: if you need to query the people working at a company and/or the company in which some person works.
More concretely, if your implementation language is Java, if you need a field of type Set<People> in class Company, you have navigation from Company to People, and if you need a field of class Company in class People, you have navigation from People to Company.
I've got a system that allows classroom instructors and graders to log in and manage classes and grade papers. A user can be both an instructor and a grader, and can be so for particular semesters. Other users, like students, are also bound to this semester scheme. Still others, like administrators, have accounts that don't run by semester.
When someone is no longer a grader or instructor, she still needs to be able to access past grading or classroom records, albeit with fewer privileges (view only).
I've thought about implementing a roles table with a semester as a part of the key, but that doesn't apply to all users. I've also thought about keeping the semester data separate from the roles, but making roles like "PastGrader" and "PastInstructor" to cover those people who need to have access to past information but should not be allowed to participate in this semester.
What is the optimal data model/roles model for this application?
I think you're on the right track. I would keep the semester out of the roles table, but use them together where needed.
Here is what I did recently that will also work in your scenario:
Create a FunctionalRole table that has the following columns:
FunctionalRoleId, FunctionalRoleName
These roles will be like jobs. Teacher, Grader, etc.
Add another table called FeatureRole, with the following columns:
FeatureRoleId, FeatureRoleName
These roles will be for specific features in the application. GradePapers, ViewPapers, etc.
Then create a third table... call it RoleMember, that has these columns:
FunctionalRoleId, FeatureRoleId
That way, the admin can assign roles more simply by the job and all of the feature roles will automatically be assigned.
And like I said, keep the semester information separate.
Gabriel
I think that you need an additional entity to help you out. You clearly have the domain object of a CLASS to represent a specific class (ie: Composition II is a class). You also clearly have a domain object for PARTICIPANT to represent the people that attend the class. I think you have already identified those two.
Next, you need a domain object to represent a specific semester/timeslot/classroom where a CLASS will be held. Let’s call that domain object a CLASSSCHEDULE. You will need a relationship from CLASS to CLASSSCHEDULE to show what topic will be taught in that room during that semester.
Now you need a domain object to represent how a PRATICIPANT interacts with a CLASSSCHEDULE. We can call this domain object an ENROLLMENT. The ENROLLMENT object is where you put your privileges for the PARTICIPANT. The PARTICIPANT is ENROLLed in the CLASSSCHEDULE as a learner or a grader. Your role is attached to the ENROLLMENT object. In this way, each PARTICIPANT will have a different privilege level for each CLASSSCHEDULE that they are involved with.
I'm still wrapping my head around DDD, and one of the stumbling blocks I've encountered is in how to handle associations between separate aggregates. Say I've got one aggregate encapsulating Customers and another encapsulating Shipments.
For business reasons Shipments are their own aggregates, and yet they need to be explicitly tied to Customers. Should my Customer domain entity have a list of Shipments? If so, how do I populate this list at the repository level - given I'll have a CustomerRepository and a ShipmentRepository (one repo per aggregate)?
I'm saying 'association' rather than 'relationship' because I want to stress that this is a domain decision, not an infrastructure one - I'm designing the system from the model first.
Edit: I know I don't need to model tables directly to objects - that's the reason I'm designing the model first. At this point I don't care about the database at all - just the associations between these two aggregates.
There's no reason your ShipmentRepository can't aggregate customer data into your shipment models. Repositories do not have to have a 1-to-1 mapping with tables.
I have several repositories which combine multiple tables into a single domain model.
I think there's two levels of answering this question. At one level, the question is how do I populate the relationship between customer and shipment. I really like the "fill" semantics where your shipment repository can have a fillOrders( List customers, ....).
The other level is "how do I handle the denormalized domain models that are a part of DDD". And "Customer" is probably the best example of them all, because it simply shows up in such a lot of different contexts; almost all your processes have customer in them and the context of the customer is usually extremely varied. At max half the time you are interested in the "orders". If my understanding of the domain was perfect when starting, I'd never make a customer domain concept. But it's not, so I always end up making the Customer object. I still remember the project where I after 3 years felt that I was able to make the proper "Customer" domain model. I would be looking for the alternate and more detailed concepts that also represent the customer; PotentialCustomer, OrderingCustomer, CustomerWithOrders and probably a few others; sorry the names aren't better. I'll need some more time for that ;)
Shipment has relation many-to-one relationship with Customer.
If your are looking for the shipments of a client, add a query to your shipment repository that takes a client parameter.
In general, I don't create one-to-mane associations between entities when the many side is not limited.