Re: Re: Pagination and sort design in ddd
Dan Haywood <[email protected]>
| Newsgroups | gmane.comp.programming.domain-driven-design |
|---|---|
| Message-ID | <CALJOYLFXpD8Hads7Ekvi8pRE1RNUtUMzqak-m2wo3b_4=yxVig@mail.gmail.com> |
Both 2 (ideally) but also 4, with metadata to indicate the page size. On 17 April 2013 14:51, raymond_kolbe <[email protected]> wrote: > > > > > --- In [email protected], "eben_roux" <me@...> wrote: > > > > Hello, > > > > I subscribe to the school of thought that believes one should not query > the domain model. If an aggregate can provide you with the required data > then fine but one should not be fiddling with the domain model to satisfy > querying. > > > > The solution alluded to by yourself and Rickard I believe is the correct > one. > > > > If you want to go for a seperate bounded context that handles > pagination/sorting then that is ok too. If you are so inclined you can > represent your sql statements using some query object (having a query > object represent a raw sql statement is also fine in some cases). > > > > You could go as far as having this BC execute the query and store the > paginated/sorted results in working set data structures that can simply > return a generic structure for presentation purposes. These would of > course expire after some timeout and can then be cleaned out. > > > > Hope that helps. > > > > Eben > > > > Hi all, > > I'm bringing this thread back from the dead in the interest of cataloging > the implementation aspects of pagination/sort w/regard to DDD repositories > (attempting to not break the UL under certain use-cases). > > Assuming that pagination is not part of the UL, but rather an aspect of > performance/view concern, I understand the following implementation > solutions to exist (including, but not limited to): > > 1) Return a *Query Object* and allow the client to add additional > constraints. I would argue this goes against the UL for a BC and I would > urge people to avoid when possible. This is a leaky abstraction into what > the repository is responsible for in my opinion. > > 2) Return a *Lazy Collection* (for a lack of a better term). Essentially > this looks and acts like a regular collection but it may choose to defer > populating the collection until the first item in the collection is > requested. Alternatively, calling *slice* on the collection would return > a specific portion of the collection, possibly returning another *Lazy > Collection*. > > 3) Return a *Paged Result* obj. My understanding is that this would be a > fully instantiated collection where *getIterator* returns the current * > slice* and *count* returns the total collection sum. E.g. *Paged Result* objs. > are a slice of the total collection so no lazy fetching is performed. > > 4) Return a full *Collection* and rely on caching on the client side. > > To give some context to how I got here I'll explain the problem I'm > working on. I have an aggregate root called *Assignment* which contains > an association to an *Employee*, *Topic*, and *Records*. The records > provide us information about whether or not the employee is current with > their topic training (*Topic*), and also provide an audit trail of when > the topic was taken. Some information is kept on the *Assignment* such > as "required", "last taken on" and "status". Status and last taken on being > VOs, telling us whether the employee is "Current", "Expired", or "Unknown". > > Anyway, the *AssignmentRepository* has a method called > getRequiredAssignmentsForTopic($topicId). This is used in the domain by the > web application (for viewing) and for a reminder system (for notifying of > upcoming expiring topic training). In two use case we ask for all > Assignments for $topicId (reminders and exporting to CSV, PDF, whatever), > and in a third use case we want paginated results for the web. > > How do others handle this? I'm aware of other solutions as well but I > would like to hear what others think. > > >