Search This Blog

Showing posts with label DDD. Show all posts
Showing posts with label DDD. Show all posts

Tuesday, April 8, 2014

CQRS Appendix

I finished the Appendix on CQRS in the book Implementing Domain Driven Design.

I really liked the appendix. It was written by a different author, and he provided very detailed code and explanations. There is even an example project on github.

I searched for my more information about the author and found a blog post where he mentioned Greg Young's Event Store. I didn't know this existed but it sounds pretty cool.

Monday, March 17, 2014

14 chapters down one appendix to go

I finished Chapter 14 on the Application of Implementing Domain Driven Design.

We have had the "What should go in a Application Service and what should go in a domain service" discussion here at work many times. At one point, the author claims I am going to clearly answer this question for you. I thought great I won't have to stress about that anymore. I feel like a broken record saying this but ... I was hoping he would give more details in his explanation because it still doesn't seem clear to me. What I got from what the book is that Application Services are for handling transactions and security. If you are doing more than creating an entity and adding it to a repository then you may have a "significant process" that needs to be modeled in the domain. He talked a little about Application Services that are for querying. I couldn't find any rules of thumb though about when your queries have too much business logic and should be domain services themselves. He did mention that sometimes you need to convert your application service into its own bounded context. I can think of one place in our code that might benefit from this idea.

There are no more chapters in the book. There is an appendix about CQRS written by someone else which I plan to read, but for the most part I am done with this book. I can't say I enjoyed reading it. I was really hoping it would answer a lot of questions for me, but I really don't think it did. I did some learn some things but not a whole lot. I guess the author's writing style just doesn't fit with how I learn. He probably knows a lot of stuff that can help me, but whatever reason I just didn't get that information from this book.

Tuesday, March 11, 2014

Bounded Context Integration

I finished Chapter 13 on Integrating Bounded Contexts of Implementing Domain Driven Design.

In our domain everything is jumbled together in one giant bounded context. Having never done what the author describes I found this chapter very interesting.

I liked the discussion about messaging. I had never thought about messages arriving out of order. I thought the author came up with a very simple solution to what could be a very complicated problem.

I also liked the discussion where he modeled a long running process as an entity and setup trackers to do automatic retries. I had to do something similar with a third party service our application integrates with. The code I wrote was very specific to the one area I was working on though. If you did this type of integration in multiple places in your application, then I could see that having more generic reusable components could be very helpful.

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.

Monday, January 20, 2014

Show me the code

I finished Chapter 8 on Domain Events and Chapter 9 on Modules of Implementing Domain Driven Design. I liked the author's explanation of how to integrate two different bounded contexts using events. He gave a couple different options like setting up a REST feed of events and also using a third party messaging tool. I thought both examples were clear and easy to follow.

He also mentioned you could use events to hook your domain to your application layer and also use events to hook up different components within your domain. He gave an example he called contrived for hooking the domain to the application layer. It was basically a method on an aggregate that did nothing but raise an event which was caught by an application service that added something to a repository. It wasn't very helpful to understanding the concept he was trying to explain. Also there were no examples of how to use events inside your domain model. I thought I might get more information by downloading his source code, but I checked the java and .net versions and their were no examples there either.

I am also reading the Big Nerd Ranch iOS book. I was struck the other day by the difference in the author's styles. In IDD the author starts with a lot of details about what he is trying to explain then sometimes follows that with a snippet of code that may or may not help explain his theory. By contrast the Big Nerd Ranch book starts out with a bunch of code that you can compile and run. The Big Nerd Ranch author warns you that you probably won't understand what you are typing but urges you to type it anyway. Once you have a working example they then go back and explain what you typed. I like the Big Nerd Ranch style much better. I can digest the theory a lot better if I can look at the actual code. I think in some ways I read code better than I read English.

The modules chapter was pretty thin. The one thing I got excited about was when he said not to create a separate folder for each component like factories, repositories, value objects, etc ... We have this Services folder that I don't like because it groups all these random services together that are in no way related. Later in the chapter he did say you could have a separate model and services folder if you treat your services like a thin layer between the domain and application. I am guessing though he still wouldn't recommend dumping all the services in there. Instead you still need to break that folder up into submodules if you have more than handful of services.

Tuesday, December 31, 2013

Random thoughts on Domain Services

I finished Chapter 7 on Domain Services of Implementing Domain Driven Design. In this chapter the author mentioned it was a good rule of thumb to not pass repositories into entities. We follow this practice at work as well. Someone recently challenged me on this practice, and I didn't have a great reason to give to them on why we chose to do this. I thought it had something to do with persistence ignorance, but I couldn't remember exactly why we instituted the practice. Unfortunately the author really doesn't get into the reason why you shouldn't do this either.

The author also recommended to not put a separate interface on your domain services unless you have know you are going to have to vary the logic of the service with different implementations for different customers. We also follow this practice, but I feel like it would be easier to mock the domain service when testing an application service if the domain service had a separate interface. The author doesn't explain how he tests his application services.

The author did call out that there shouldn't be any business logic in the application services. He didn't really get into how he defined business logic though. We frequently get into discussions at work about whether some code should be in the domain or just in the application layer. The discussion usually ends up at is this code business logic or not. I think if we have AC around it and we would want multiple UIs (desktop and mobile) to follow this behavior then it is probably business logic.

Wednesday, December 4, 2013

Passing in more than needed

I finished Chapter 6 of Implementing Domain Driven Design. I am still not enjoying this book even though I will force myself to continue. Again the author promised many times he was going to reveal this really important bit of knowledge of how we are overusing entities and should be using value objects more in the domain. I thought he was going to talk about the return values from domain services and how those things are really important pieces of the UL. Instead his examples were more about avoiding primitive obsession. It is important information but I guess it was just not what I was hoping for. The next chapter is about Domain Services so maybe the information I am looking for is in there.

He did make one point I found interesting. He said that when you design a method definition you shouldn't pass in the whole entity if all you need is one value object off that entity. I have been doing the opposite lately. I try to make the client of the method as dumb as possible and put the logic of what needs to happen in the method doing the work. I find this makes reading my code easier. His point though was that you can't be sure that your method is side effect free if you pass in the whole entity. Also he said it makes testing harder to pass in the whole entity because you have to setup more data to pass to your method. I agree with both of his points. I am not sure I am ready to change my style yet, but the balance of pros and cons has definitely been shifted.

Tuesday, November 5, 2013

Domain Services are part of the UL?

I finished Chapter 5 of Implementing Domain Driven Design. I wanted to poke my eyes out while he was describing how to handle an id, but I really enjoyed the part where he started talking about how we would model a User. I liked that he talked through how he made each design decision and what other alternatives were considered. It was a pretty simple example, but I think he was able to pack in a lot of good tips.

One thing I thought was interesting was how he decided to include his DomainService in the UL. Sometimes I see really generically named services called <AggregateName>Service where AggregateName could be any one of the Aggregate Roots in our domain. Usually those services are catch all bucket for a whole list of very loosely related methods. I think if the DomainService's name were part of the UL then people would probably name it something more specific. I also wonder if having a specific name would reduce the number of things the service does down to one thing. Hopefully having each service have one responsibility would make these classes a lot easier to understand and maintain.

At the end of the chapter the author starts talking about validation. I remember our team having the hardest time figuring out how to do validation that requires a UnitOfWork. He didn't really talk about that problem much other than mentioning you could use a DomainService or use events. Oh well maybe he talks more about it later in the book.

Tuesday, October 22, 2013

Still flying up in the trees

The book I am reading Implementing Domain Driven Design gives this metaphor of flying in airplane viewing your childhood home and seeing something you are very familiar with at a detailed level from a high level so as to gain a new perspective. My hope after hearing that was that the author was going to eventually switch gears and explain things at a detail level instead of just giving the high level view that the book opens with. I am half way through Chapter 4 and I still feel like I am flying high waiting to see how the theory is applied to reality. I wish the author would explicitly tell the reader when they shift gears. For all I know he has already shifted I am just too clueless to consider the new style to be the detailed view.

I think the book definitely has useful information. I am getting the feeling though it is not the book I was thinking it was going to be. I was hoping for a book like "Domain Driven Design Practical Example Explained Step by Step". I am still missing how to take the theory and translate it to real code.

One interesting thing I read was about the Hexagonal Architecture. It is alternative to a layered architecture that allows multiple entry ports into the application. Our architecture definitely allows multiple entry points. Our thinking was that each major system would have its own entry point and that would allow us to change the internals of the domain but keep the entry point backwards compatible so as to not break those major systems with each domain change. Looking back now I am not sure that is really any better than having one versioned public API where systems that we couldn't upgrade could still remain on the old version of the API. The other main reason for this decision was that we could easily format the information in a way that each system needed so that the client code calling our API could be simpler. At least for our UI code I think this decision was helpful.

The author warns against business logic leaking out into the different ports. We definitely screwed that part up. Many of the stories I am work on now involve removing the business logic out of the port, putting it back into the domain, wrapping it with tests, and documenting the AC. Most of this business logic is how queries should work not commands. I think are application is definitely complex enough to merit the CQRS architecture described in the book. Separating out the queries would reduce some of the dependencies but not all of them. We still have cross aggregate validation to handle. Maybe he describes the solution for that later in the chapter.

Anyways I am going to keep reading. Hopefully I will glean something useful. I am still holding out for the DDD book that is mostly code with some explanations on why they made certain decisions.

Wednesday, September 11, 2013

Can your domain expert understand your test?

I started reading Implementing Domain Driven Design recently. I am happy there is a new DDD book. Even though I have read the original book multiple times I still feel like I am messing up some of the most important concepts. Vernon mentions in his new book that many people feel the way I do and he names our level of DDD practice "DDD-Lite". I am hoping reading his book will help me transition to a deeper level of understanding of DDD. If I learn something I find interesting I will try to post it here. Below is my first submission.

In Chapter 1, Vernon suggests that your domain expert should be able to read your first test that you create to define the new behavior you are adding to your domain model. I like this idea, because I think it will give you a good way to measure whether you really are creating a ubiquitous language and using it to design your code. If the domain expert can't understand your first test then your code is probably too complicated and you may not be getting the full benefit of DDD.

At work we create XML based tests that get translated into code. Part of the reason for creating the XML based tests was so our domain experts could read them. I think I like Vernon's solution better to this problem though. I like his solution better because our XML based solution allows us to write domain code that doesn't match the domain experts understanding of the problem and still show them domain tests that makes them think we understand the problem. The XML based solution is kind of like a cheat that covers up the real problem that our domain code is too complicated.

Wednesday, June 24, 2009

Repositories And Abstract Classes

Ran into weird problem where my Aggregate Root was an abstract type with many concrete classes. Should I have one Repository for each concrete class or one Repository for the base class?

I couldn't find anything in the big blue book or online so I made something up. I have one Repository for the base class. Then each GetByXXX method is a generic method that takes the type of objects you expect to get returned. So you can get a list of the base classes or a concrete type or an interface that allows you to group concrete types together.