i'm not sure how to model this relationship...
A cl开发者_如何学编程assroom contains many seats, every student studies in a classroom and have a favorite seat within it.
The way i see it, i have two aggregate roots: classroom and student, seats a are entities aggregatged by classroom...
And for a student to have a fovorite seat, it must hold a reference to it (seat isn't an aggregate root).
Any suggestions? Thanks in advance, Erik.
Hmm, it depends... I'd maybe have classroom aggregate with seats like you. Students could be entities, but seats look more like value objects to me. However, all that depends on your context. I am not sure what is important for you, if my suggestion doesn't make sense, please explain your context.
A possible option would for each seat have a list of the students that the seat is favorite of. The Classroom aggregate root would be responsible for maintaining the constraint that a student can not have more than one favorite seat in the classroom. With this option seat is an entity (not a value object) aggregated by classroom with references to the students.
It sounds like you need to introduce a value object, Location
, which describes a spot in a classroom, and you can then model them like this in the student class:
public IDictionary<Classroom, Location> FavoriteSeats;
Classrooms can reference Seat
entities by their locations.
(If they really are entities in the first place - you may even discover that you don't need to model seats as entities (e.g., "The blue plastic chair that smells like hamburger).)
Months after the OP, but just in case it's useful.
@Jeff Sternal is on the right track. The problem is fundamentally about managing a 3 way (ternary) relation among students, classrooms and seats. Since it's a relational problem, let's stay with relational concepts for now and call it FavouriteSeat(Student, Classroom, Seat).
As described, the problem doesn't require any knowledge about any of them other than a unique identifier. Let's use a pseudo type 'ID' for now (doesn't really matter, as long as each is unique).
In pseudo-sql, we have:
create table FavouriteSeat(
StudentID ID not null,
ClassroomID ID not null,
SeatID ID not null)
Standard CRUD (create/read/update/delete) ops on that table provide all the operations required. However, it's missing some constraints. Right now, a student could have 2 or more favourite seats in a classroom. Although not explicitly stated, the OP implies that a student should have at most one (0 or 1) favourite seat in any given classroom.
We can fix that by adding a unique key on the table. Again using pseudo-sql:
alter table FavouriteSeat add unique key (StudentID, ClassroomID)
Now a student can only have one favourite seat for any given classroom. There's still a remaining question. The solution doesn't currently support defining what seats are available in what classrooms. We can solve that by:
Adding a new table that lists the valid seats in each classroom:
create table ClassroomSeat ( ClassroomID ID not null, SeatID ID not null)
alter table ClassroomSeat add unique key (ClassroomID, SeatID)
Adding a foreign key to the FavouriteSeat table so it can only reference valid ClassroomSeats:
alter table FavouriteSeat add Foreign Key FK_Seat (ClassroomID, SeatID references FavouriteSeat (ClassroomID, SeatID).
That's it. 2 relations, 3 keys and standard CRUD operations cover all the requirements as stated.
The relational model can be translated in OO/DDD pretty easily. It needs an Entity for FavouriteSeat and ClassroomSeat with methods for the CRUD ops. The methods would have to enforce the unique & foreign key constraints above.
To meet just the requirements stated, Customer, Classroom and Seat could be value types (although there may be wider unstated reqs that may change that). Either way they need a unique identifier property that can be checked in the FavouriteSeat methods.
精彩评论