0

How would you deal with an aggregate root that has a large set/ collection? Here's a concrete example similar to what I'm currently working on:

Say I'm working on an application that helps an academic institute scheduling their courses. An "Instructor" can schedule a "Course" for any time in the future (no max limit). An invariant rule concerning scheduling a course says that scheduling a course that overlaps with an existing one by the same instructor is not allowed.

My solution was to have an aggregate whose root is an instructor plan. The root "has-a" collection of courses planned for that instructor which allows determining the consistency of this aggregate by checking the validity of the aforementioned invariant.

The problem is that as the system grows, this list of planned courses may become huge, and I don't think it would be wise to fully load it as I'm assuming it would have a big footprint on the memory (something we're already struggling with in this application).

Is it good design decision to limit loading the collection of courses to a specific period e.g.: for a week or a month? or even better the ones in the future?

2 Answers2

1

This is a modeling issue, not a technical one. Humans have always introduced bounds for time-bound collections: e.g. fiscal years, school years, or simply units of time. I have yet to come across a domain where - after spending a fair amount of time in it (oh the irony) - I couldn't come up with a natural way of slicing up that unbound collection.

As @MikeSW mentions, we often fool ourselves with this container/storage/parent-child mindset and desperate attempts at translating that into code. Sometimes all it takes is thinking of it as a way of classifying things. Other times looking for missing concepts such as natural boundaries could help.

Even so, there are things you mention that I wouldn't be able to accept without further clarification. For one, I don't buy into "no max limit". How far ahead are we planning? What's the maximum lifespan of the career of an instructor? How do we know what courses will be popular/in demand in the future and how does that affect planning? I could continue this line of questioning, given a domain expert on the other end. Another odd invariant is that "courses for the same instructor can not overlap". Maybe there's a difference between a future course and a scheduled course. I have little experience in this domain, but I do know there's specialized software that solves the puzzle of setting up a curriculum for teaching facilities, students and instructors. Also consider what are reasonable amounts of courses for one instructor to offer in the future. I can imagine some preparation goes into them. There's little collaboration since it's one instructor maintaining his set of future courses. Maybe planning courses could be a separate activity, maybe ... again, satisfy your curiosity and answers will come.

Yves Reynhout
  • 2,982
  • 17
  • 23
0

This question has actually come up a number of times in different guises :)

Here is one of my recent answers:

DDD: How to handle large collections

Is it good design decision to partially load the collection of courses e.g.: for a week or a month? or to load only future ones?

From a repository I would say "No".

For a query layer it would be a definite "Yes".

Any planned course is, by its very nature, future related since planning is a future related activity. I am going to assume an instructor isn't going to be planning too many courses so one could have any courses not yet completed as part of the aggregate. As soon as it has been completed it could move to some historical store.

That being said, an AR should contain entities if those entities cannot exist without the root. If that is true in your case then it makes sense. From your invariant example it may very well be OK.

If you have had a look at CQRS then you could have a query layer that can be used to find any filtering of courses (planned / historical).

At the end of the day you certainly do not want large collections in your AR and one should always strive to re-model in such a manner as to avoid them.

Community
  • 1
  • 1
Eben Roux
  • 12,983
  • 2
  • 27
  • 48
  • If you agree that the consistency boundary includes the plan and the future courses, why is it a "No" to have the repository returning future courses? – Shameless Developer Aug 27 '15 at 06:38
  • I interpreted your question as being somewhat of a "query" (week or month). An AR should *always* include everything that makes up that AR so if you model it to include all the planned courses then it is fine. It will not be performing any query then. Querying on repositories is not the best idea. Hope that makes sense :) – Eben Roux Aug 27 '15 at 07:50
  • It does, and this takes us back to my original question, is it OK to say that what makes up this AR is an instructor plan containing a list of future courses as opposed to all courses ever planned? – Shameless Developer Aug 27 '15 at 08:57
  • No reason why it shouldn't be OK. – Eben Roux Aug 27 '15 at 09:03
  • @ShamelessDeveloper If I've understood correctly, you want to treat the AR as a container. That's not ok. In DDD, "has a" means "is defined by" in 99% of cases. Your InstructorPlan is basically a grouping criteria for future lessons. So, I'd say keep things as a service: `AddLesson(planId,lessonId)` and use a query to get the lessons. The `InstructorPlan` AR should consist of the plan name , but no 'children' lessons. An AR is **never** a container, just a concept that can be defined by more than one part. – MikeSW Aug 27 '15 at 15:59
  • MikeSW is absolutely correct. An AR will not contain a list of other ARs for containment. But Mike, since `Course` is probably going to be an AR iit would probably be OK for a `PlannedCourse` with a `CourseID` and dates to be part of the `InstructorPlan`, not so? Once again, this all depends on the UL and understanding the domain. I do think there is some food for thought, though :) – Eben Roux Aug 28 '15 at 04:32
  • @MikeSW very interesting article. But which part of my question gave you the impression that I want the AR to be a container? I thought that I made it clear that the reason for this aggregation is to have a consistency boundary that allows determining the validity of the invariant. – Shameless Developer Aug 28 '15 at 17:38
  • @EbenRoux A `PlannedCourse` is basically an association criteria of an instructor and a group of courses. IMO, we define the criteria as an AR but the setting of the associations should be a domain service which ensures constraints and technically just stores ids in a table. Aggregates are concepts, not collections of references. – MikeSW Aug 28 '15 at 17:56
  • @ShamelessDeveloper It gave me the impression that you want to hold all courses ids into `PlannedCourse` therefore treating the AR as a container. As @Yves Reynhout said, we need way more insight into the Domain, you clearly know more than us about it and we can give you only some thoughts based on the little info we have and our general DDD experience. – MikeSW Aug 28 '15 at 18:02