Search This Blog

Sunday, February 9, 2014

Finished repository chapter

I finished Chapter 12 on Repositories of Implementing Domain Driven Design.

I thought the discussion he had on the performance benefits of Toplink was interesting. I remember having a similar discussion a while ago where we considering using stateless sessions for our readonly web services. This isn't quite as good as the Toplink design since even on our write operations we typically read data we don't intend to modify to do various types of validation.

I was little surprised he supports use case optimal queries which from what I can gather is using sql to create DTOs or value objects and returning them from your repositories. I would have thought he would only recommend that in cases of extreme performance problems. He did say if you are doing it a lot then it is probably a code smell.

He also has a section about Type hierarchies and how you should limit use of them. I tried implementing a Type hierarchy in NHibernate and it didn't go well for me. He had some good ideas about how to hide the types inside the aggregate and how to not let them leak out to be used by other aggregates.

I was also surprised he didn't give an example of how to test a repository with a mock. He did give an example of how to test with a real database and with a stub though.

Tuesday, February 4, 2014

The rules of aggregates

I finished Chapter 10 on Aggregates and Chapter 11 on Factories of Implementing Domain Driven Design.

I remember talking about Large Cluster Aggregates with one of my coworkers when we first started trying DDD. We didn't call them Large Cluster Aggregate at that time we just had two opposite ways we wanted to design our aggregates. We worried that if we didn't use large cluster aggregates then we would have an Anemic Domain Model. We felt like if we did use them then we would run into some bad transaction/performance problems. Erring on the side of caution we chose not to use them so I was happy the author also recommended not using them.

I also remember us discussing whether to reference everything by identity or by the entity. Even though we have a coding standard that says reference by entity I still think we reference by identity at least 50 percent of the time. I always preferred identity but I never had a really good argument of why. I think referencing by identity does make it more difficult to build up the data needed to generate a UI. For example a UI displaying a list of articles should probably display the author's name and not the ID of the author. When referencing by identity this usually means you need to query all the author's and then join them back with the articles in memory to create the DTOs needed for the UI.

The author talked with Eric Evans, and they came up with a good rule for when to be transactionally consistent and when to be eventually consistent. If it is the job of the person making the request to make the two aggregates consistent then be transactionally consistent. If it is someone else's job to make the two aggregates consistent then be eventually consistent. This mirror's what happens in real life and makes sense to me. When you get married your HR person does not instantly change your tax withholding while you stand at the altar. You change your tax withholding at some reasonable time in the future.

The author also mentions to not inject repositories or domain services into Aggregates. Even though the topic is heavily debated at my work we are currently not injecting repositories into Aggregates. We do in some cases though pass services into our aggregates using a Double Dispatch technique. Unfortunately the author does not give a lot of detail into why he recommends you don't pass repositories into Aggregates. I wish there was a book or pdf that had all the generally accepted good DDD practices and a short explanation of why it is a generally accepted good practice. Maybe things aren't that black and white though.

The one thing I took away from the factory chapter was that he recommended using factory methods instead of separate factory classes. I have never been a big fan of our factory classes since they seem to just initialize the properties on our classes and do very little work. I think mostly I just don't like calling a method with 10 parameters. Half the time you can't figure out what those parameters mean without drilling into the factory. What does that 5th parameter that is null represent? I guess the factory methods could reduce some of those parameters. I also like the idea of using the builder pattern instead of factory if you have a bunch of optional parameters.