Domain Driven Design encourages you to use a rich domain model. This means all the domain logic is located in the domain model, and that the domain model is supreme. Persistence becomes an external concern, as the domain model itself ideally knows nothing of persistence (e.g. the database).
I've been using this in practice on a medium-size one-man project (>100k lines of Java) and I'm discovering many advantages, mostly the flexibility and refactorability that this offers over a database-oriented approach. I can add and remove domain classes, hit a few buttons and an entire new database schema and SQL layer rolls out.
However, I often face issues where I'm finding it difficult to reconcile the rich domain logic with the fact that there's an SQL database backing the application. In general, this results in the typical "1+N queries problem", where you fetch N objects, and then execute a nontrivial method on each object that again triggers queries. Optimizing this by hand allows you to do the process in a constant number of SQL queries.
In my design I allow for a system to plug these optimized versions in. I do this by moving the code into a "query module" which contains dozens of domain-specific queries (e.g. getActiveUsers), of which I have both in-memory (naive and not scalable) and SQL-based (for deployment use) implementations. This allows me to optimize the hotspots, but there are two main disadvantages:
- I'm effectively moving some of my domain logic to places where it doesn't really belong, and in fact even pushing it into SQL statements.
- The process requires me to peruse query logs to find out where the hotspots are, after which I have to refactor the code, reducing its level abstraction by lowering it into queries.
Is there a better, cleaner way to reconcile Domain-Driven-Design and its Rich Domain Model with the fact that you can't have all your entities in memory and are therefore confined to a database backend?