views:

97

answers:

2

I have been building a new application using my current understanding of domain driven design. So far I have a bunch of classes representing entities in my domain and a repository to retrieve from/persist to the database.

The problem I am running into is that in the UI I have a need to display a few lists where the items in the list don't map directly to any entities in my domain. Some of the list could be built by doing a fairly deep eager load of certain entities, but other data is essentially synthesized at retrieval time and is not part of any entity. Let me provide an example that will hopefully explain the problem more clearly.

In my domain I have evaluations (a set of questions to answer) and responses (the answers that each user has provided to the evaluation) to those evaluations. I also have actions. Each action represents an action that has been taken with a response (submit, approve, reject, etc.). I also have users.

One of the lists of data that I need to display would include responses and evaluations (that have not been responded to), then each line would include information about the user who is currently working with the response (this is determined at retrieval time by looking at the actions that have been taken on a response). Each line item would also include zero or more child items which are actions that have been taken on the response so far.

The problem is that as of right now I don't have any way to represent this entire data set with my domain entities. My first reaction would be to just retrieve a datatable from the database and bypass my domain entities. But I see a lot of value in working with domain objects and having the relationships between different entities baked into the objects themselves. So my next idea would be to modify my domain entities to support these lists, but I am concerned both that I would be adding strange properties to my entities just to support these listing scenarios and that I might be hurting performance by essentially doing deep loads of objects when I only need that data in a few places in my apps.

+2  A: 

I'd suggest not viewing this as something you have to shoehorn into your entities, but rather provide a service (in the domain-driven design parlance) whose job it is to collect this data when requested and present it as a view. This frees you up from having to rework your entities in an clunky way.

The problem is that as of right now I don't have any way to represent this entire data set with my domain entities.

The awkward design friction you're feeling here is a good thing. It's a clue that things aren't quite fitting together.

John Feminella
Ok, I'm now reading up on services. When you say the service will present the data as a view, what is the view? Is it a class that is defined just for this purpose? Is it composed of domain entities?
Mark Kanof
I'm using view in the MVC sense -- that is, something whose job it is to show you things. The actual relevant data would be aggregated by the service, which the view is then handed and asked to display (in your case, that's the "list of data" you mention). A service may well decide to wrap things up in separate classes (particularly if many views use the same data) before handing it off to views, but that's by no means required.
John Feminella
+2  A: 

Sounds like you have, (through the appearance of this difficulty) identified an issue with your domain model. The abstraction you want to display in each of these list boxes is, apparently not well represented in your domain model, nor in your "ubiquitous language". Decide what it is, name it, and add code to your repository to generate lists of these objects, whether they turn out to be entities or value objects...

Charles Bretana
Indeed - I may be misunderstanding the problem at hand, but my initial impression is that the domain entities just need additional properties: i.e., Response entities should have an Actions (or ActionHistory) property to represent "actions that have been taken on the response so far."
Jeff Sternal
Sounds like you understand the issue I am having. I am considering adding those additional properties, but honestly part of my concern with doing that relates to possibly loading way more data than I really need at certain times. The actions are pretty straight forward and would not be a problem, but my user entities are pretty complex and it seems like a lot of extra work to load the entire user when all I really need is the user id and name. But partially loading an entity seems really hacky to me.
Mark Kanof
If it's a performance / optimization issue, then John Feminella's answer (to create a service method to handle it) would definitely be appropriate. Having said that, a lot of OR/M tools will let you lazy-load these properties (which is moot, of course, if you're not using one of those or rolling your own data access layer / repository).
Jeff Sternal
I would like to be using NHibernate, but due to some business constraints that I won't get into, I ended up having to roll my own ORM. I'll take a deeper look at the service approach proposed by John Feminella.
Mark Kanof
If an entity is too complex for one function it is being used for in your application domain, then perhaps it needs to be broken into smaller, simpler abstractions, that better fit with the application's functional requirements.
Charles Bretana
One thing I have learned from DDD is that the abstractions in your domain model do NOT (and should not) have to be reuseable across multiple as yet unknown client applications
Charles Bretana