Posts tagged architecture
Domain-Driven Design by the book
Sep 6th
Starting a new project is fun. You (assuming you, reader, are The Architect) can make all the decision and do it right. You can use all the newest technologies you can find. And what do you do when it comes to designing business logic? Hopefully you base you decision on the level of complexity of the problem you are solving. If the problem is relatively easy, you implement a CRUD solution, right? On the other hand, if it looks really complex, you can enjoy having a good reason for CQRS architecture. But what’s between these two extremes? Enter (again) classic Domain-Driven Design by the book. I understand that in this CQRS noise you could forgot about this option. Let me remind you about architectural properties of such design.
10.000 feet view
The best way to describe such system is to use Jeffrey Palermo’s Onion Architecture approach. Domain model is the most inner layer of the onion. It contains your business logic and does not depend on anything significant (like WCF or NHibernate). The next layer of the onion would be something I usually call Application Layer. Notice that I skipped Domain Services Layer. It was intentionally. I consider domain services (if you really, really need to have them) part of the domain model. Application Layer is where your commands and command handlers live. For each business action there is a pair of a command and it’s handler. Trust me, making business operations explicit by implementing them as classes (as opposed to methods on a class/interface) pays off in the long run. If the application has a user interface, it is the outermost layer of the onion. If not, the Application Layer becomes the outermost one with it’s commands exposed via some remote interface (like WCF or NServiceBus).
Repositories and data access
You probably know I am a fan of repositories. I like the explicitness of their interface. In the architecture we are talking about you would probably use some kind of ORM (like my favourite NHibernate) so repositories would end up being a thin wrapper around the almighty mapper library. Using an ORM also implies that you have a Unit of Work in your solution. Most (probably all) of the major mappers have it implemented so it does not make any sense to not use it or write your own implementation.
Aggregate boundaries
The corollary of having a unit of work is the possibility of violating the aggregate boundaries. It needs discipline (and you, as The Architect, are the one who is responsible for maintaining it) to avoid transactions spanning multiple aggregates. Why is it so important? Because Aggregate Roots are usually used as concurrency units. Involving two concurrency units in a transactions can lead to all sorts of nasty things, including race conditions and deadlocks. There is one exception to this One Transaction-One Aggregate rule, namely creating new aggregates. Because newly created aggregates, for obvious reasons, can’t be involved in two transactions (thus causing concurrency problems), you can create them as part of a transaction initiated for another, already existing, aggregate.
Of course, you can read as much as you like, also from other aggregates.
Testability
There are several things you can test in such solution, each of which requires a different strategy. First of all you should test your domain model as it is your most valuable asset. You can read more about it in one of the previous posts. For testability reasons you should strive to squeeze as much business logic in Value Objects as you can. The remaining logic will be placed on the entities.
Another thing worth testing is persistence. You have to prove that you can persist and load objects in any valid state. Because it would be not practical to test for all the valid states, I would recommend testing for the most complex states. Odds are that simpler states will just work.
Application layer tests are also worth the effort. They come in two flavours: with mocked repositories and with real repositories. It depends on particular case which one is more useful. Testing with real repositories requires of course some database. The easiest ones to use in test environment are SQLite and SQL Server CE.
Last but not least, there is usually some UI code (like controllers) to be tested. Don’t forget about it.
Events
Yes, the events have their place also in this architecture. We need them because they are the ultimate integration mechanism. You can do all sorts of cool things if your system publishes the changes to its internal state as a serious of events. If you don’t believe me, read or listen to Udi Dahan when he talks about SOA done right.
You can implement events in a classic DDD solution in two ways. Either make them a separate concept like in this article of Udi or make them part of your domain model (as proposed by Eric Evans in one of his great presentations). I consider the latter approach cleaner but more difficult to implement properly. The choice is yours.
User interface
Some systems really need a user interface. Really. From time to time it is good to display something to the user and let him make some decisions. It makes users feel important etc. So how do you get the data out of the store so that use can see it? As you may have read before on this blog, I am a big opponent of using repositories for getting the data to the views. This is a separate responsibility which I like to implement in Finder classes. Another issue is, how you implement these finders. As usual, you have more than one option. One is to have a set of classes parallel to your domain model that are mapped to the same tables in the database. Of course you would also need another set of ORM mappings. You can read more about this approach here. Another, also valid, approach would be to map domain model classes to DTOs using a tool such as AutoMapper. I hear you saying that mapping domain objects to DTOs is considered an anti pattern. I guess I have said it a few times. But what I am proposing here is a bit different. You should encapsulate the way you get your DTOs in the finders so that it’s not an architectural issue any more. If it’s not an architectural issue, it can’t be an anti-pattern, right? You may have some finders that issue a plain old SQL, some that map from domain objects and some that use database-mapped DTOs. Use whatever method works best to solve the problem at hand and don’t forget to encapsulate the solution.
Summary
I would like to hear from you what do you think about this architecture. For sure it’s not the ideal one, the one you dream about. But I’ve implemented it a few times and it worked reasonably well. Do you have any ideas how can I improve it without introducing additional complexity?
Testing strategies for business logic
Sep 1st
Let’s talk about testing. How do you test your business logic? I spent some time thinking about it and came up with three different strategies for three different ways of implementing business logic.
CRUD
As you can read here, I think CRUD is OK for small and simple applications. You have to, however, remember what is not supported in this architecture – collections of nested objects.In the previous post I’ve written about few reason why is that. Today I will show you another one, this time related to testing. You test a CRUD application by performing a business action given some fake repository object(s) and verifying (on this fake repository) if proper objects have been created, updated and deleted.
//Arrange var orderRepo = new FakeOrderRepository(); var orderService = new OrderService(orderRepo); //Act orderService.CreateNewOrder(orderData); //Assert var order = orderRepo.Get(id); Assert.IsNotNull(order); Assert.AreEqual(10, order.Value);
That’s it, no rocket science. It would be much more difficult, however, if you allowed relations between objects. In such case you would have to verify also these relations. Moreover, mocking a repository if you support relations would be much harder. You would basically had to provide an in-memory database. If you stick to simple structures, you mock a repository using a single collection and your’re done.
The classic approach to DDD
This approach is basically a compilation of what you can find in the Blue Book and in Jimmy Nilsson’s book. It is Domain-Driven Design with objects mapped to database using an Object-Relational Mapper (remember — NHibernate). These objects have properties for getting their attributes and showing them on the UI. Of course there is no dumb setters. Last but not least, there are also value objects that are used to represent attributes with complex values.
So how do you test such architecture? You take advantage of persistence ignorance of good domain model. Prepare a domain object in state you want to test by invoking normal business methods. Once it is ready, call the method you want to test. Then verify the results by using property getters.
//Arrange
var customer = new Customer("Szymon", "Pobiega");
var product = new Product("Widgets", new Money(10, new Currency("USD")));
var order = new Order(orderId, customer);
order.AddLineItem(3, product);
//Act
order.AddLineItem(1, product);
//Assert
Assert.AreEqual(2, order.LineItems.Count())
Testing value objects is even simpler because of their immutability. All you need is to call a method on it (returning a new instance of a value object) and compare it with expected value.
//Arrange
var usd = new Currency("USD");
var total = new Money(10, usd);
var toSubtract = new Money(2, usd);
//Act
var result = total.Minus(toSubtract);
//Assert
var expected = new Money(8, usd);
Assert.AreEqual(expected, result);
The trick in testing classic DDD is to not depend on your ORM to do anything for you behind the scenes. The good example is many-to-many relation. In NHibernate, if you set value only on one end and persist the entities, both ends will be set magically when you get the object from database next time. But before that, for some time the object model will be inconsistent. Good practice for such relations is have code in domain model that explicitly sets both ends of particular relation.
Another gotcha is preparing the object state. Like I said, you do it by calling normal methods. The downside of this approach is something may go wrong in this phase of test and the tested method will be given different state than expected. My personal pragmatic approach is to do nothing until it hurts. If it starts to cause major problems you can think about adding Assert calls after the object has been prepared to verify if it really is in the expected state.
Event Sourced DDD
One of the reasons I really like Event Sourcing is it doesn’t cause any (known to me) problems when testing. If I was to name the ideal types of code for testing, the first one on the list would be functional code and event sourced entities would be right behind it.
The beauty of testing event sourced objects comes from the fact that state mutations and business logic are separated. You can mutate the state (by applying an event) without any business action. That’s how entities are hydrated from the event stream in the first place. There is also an inherent beauty in definition of such tests
//Arrange var order = new Order(); order.Apply(new ItemAddedEvent(10, productId)); order.Apply(new ItemAddedEvent(5, productId)); order.Apply(new ItemRemovedEvent(2, productId)); //Act order.AddItem(3, productId); //Assert order.UncommittedEvents.Contains(new ItemAddedEvent(3, productId));
Which translates to
Given these events had happened before, when this action is called, I expect these events to be published
Nice, isn’t it?
Summary
Of course you can’t always afford to create a fully-featured event sourced solution. For simple scenarios it’s an overkill. But that’s not an excuse for not having good tests. Every approach to structuring your business logic is testable, you only have to know what constraints you have to place on the code so that testing it is a pleasure, not a pain in the back.
What is CRUD?
Aug 30th
Quite often we see criticism of Create-Read-Update-Delete solutions. There are tons of blog posts why CRUD is inferior to Domain-Driven Design. I have probably written a few of them in my life. It seems like everybody is doing proper DDD and advocating doing it so where’s the problem? I haven’t seen so many domain driven systems in the wild. If you take a look at DDD tag on StackOverflow you’ll see that most of questions are actually concerned with CRUD, not DDD solutions. So what is this CRUD?
It is an architectural style where the centre of the solution (or the lowest layer, depending on your perspective) is a package containing structures that represent data in the real world. These structures are usually mapped one-to-one to database tables using some kind of Object-Relational Mapper (NHibernate, remember?). Upper layers contain stateless service classes that operate on these structures.
Modern CRUD architectures borrow much of the terminology from Domain-Driven Design which confuses many people. You can find entities (a fancy name for a data structure), repositories (another fancy name, this time for Data Access Object pattern), domain services (place where the logic lives in CRUD) and so on. Please bear in mind that in the rest of this post I will be using these terms in context (and meaning) of CRUD, not DDD.
So, is CRUD inferior to Domain-Driven Design, like I suggested at the beginning? Not really. It has different architectural properties. It probably doesn’t scale as well when complexity grows. CRUD earned it’s really bad opinion because it can become quite messy if you don’t understand it’s essence.
And the essence of CRUD is Create-Read-Update-Delete. Period. You can do these four and only these forur operations on any entity. As you can see, there is no support in the architecture for establishing one-to-many relations. To be precise, there is no support for entities having collections of other entities. Why? Suppose you have a Parent entity that contains a list of Child entities. If you add a new Child entity to the collection, what should happen? It could be translated as “Update the Parent, Create a Child and AddRelation between Parent and Child” but also could be translated as “AddRelation between Parent and Child”. There is no language in CRUD to define logical relations between entities (like in DDD between aggregate root, entities and value objects) that can help to deal with such ambiguities.
What you can do is stick to many-to-one side of relations if you need them. Looking from Child’s perspective, the aforementioned operation would be unambiguously translated to “Create Child” if child entity doesn’t exist yet or “Read Child, Update Child” otherwise. The reference to it’s parent is part of it’s definition so Update operation can deal with it. But what if you need to get a collection of children of some entity? You can always use repository to query the data source, right?
To sum up, if you happen to build a simple system, please don’t throw DDD at it. It would be both an overkill and a mess. Remember, CRUD can be you friend if you understand it’s rules and follow them. Don’t try to make it DDD-Lite.
WCF, you are doing it wrong!
Aug 26th
If you are using WCF directly you are probably doing it wrong. Yes, I mean it. If you implement your service in one huge class you are doing it horribly wrong. Let me explain why.
Such a class is a violation of Single Responsibility Principle. The service class is doing few, usually completely different, things because so called service operations usually have little in common. That manifest itself in very low cohesion — often times the only field of the class that is used by more than one method is called log (or _log, depending on your conventions). Because each of these methods usually need 2-3 collaborating objects to achieve its goal, our service class ends with dozen or move dependencies. Does anything of this sounds like a good design practice? I don’t think so.
There is also another aspect of having huge service classes with many methods (called operations in WCF lingo). We don’t see messages. Instead, we have methods with parameters and return values. While this makes novice developers feel comfortable (no new stuff to learn), it makes some advanced things like request validation, automated logging, establishing processing context (e.g. opening NHibernate session) much more complicated.
Solution is really simple. Actually, there are two
- use Davy Brion’s Agatha framework
- write something similar yourself
No matter which way you choose, the goal is clear – you should not program directly against faulty WCF API. Instead, you should define concepts like
- messages (requests and responses)
- validators (ensure request is valid)
- filters (do some action before and after request is handled)
- handlers (do actual stuff)
and have some generic piece of code that handles translation of these to WCF primitives that sit under the hood. I wrote one myself and it took me less than a day. It’s really easy.
On the Repository pattern
Aug 23rd
The Repository pattern is one of the most popular patterns of enterprise application architecture (P of EAE, a great book by Martin Fowler). The pattern was further refined in context of Domain-Driven Design by Eric Evans. Since then wars has been waged around how to implement a Repository and when to use it. Here’s my take on this subject.
First of all, Fowler’s definition of Repository
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects
should not be treated literally. Providing a collection-like interface for relational database can be a problem much bigger than posed by most of the ‘enterprise’ systems that are being built today here and there. I would suggest a more practical ‘working’ definition like this one
- Provides access methods to domain objects
- It is meant to be used by command handlers
- Returns one object or throws exception
- If it is designed to work with Unit of Work, has no Save method. Otherwise, it has
- The interface is placed in same assembly as domain model classes
The first line is pretty obvious, right? The second could be more problematic. In my opinion the very reason why we create repositories (and I do believe we should do it) is the ability to write more explicit code in command handlers (or whatever approach you use in Application layer). There are, however, cases where repositories can be useful outside of command handlers. When employing the classic approach to DDD (synchronous, without CQRS, EventSourcing and other cool stuff) we often have to display a domain object on screen. In such case we can use a repository to retrieve our object. It’s not a deadly sin son, I forgive you.
Returns one object or throws exception… Why? Because we don’t invoke any action on a collection of domain objects. Ever. If you want to display a grid, please create a separate class (I would call it Finder) for this purpose. I am pretty sure you don’t want to display all the data associated with a domain object on a grid, so your finder will probably retrieve only a subset of information. If you need the data only for display purposes, it can be a little bit stale, so you can add caching. If I haven’t convince you yet, think about change management. Do you really want to change your repository (which is part of Domain Model) every time you add a column on a grid on some UI form? I bet no. So please place all the finder methods outside of the repository.
But what if you want to invoke an action (change state) on a collection of object? The answer is simple. You are probably missing a real-world domain object which corresponds to this collection and should be the sole owner of the piece of data you want to change. Find that object and model it explicitly in your solution.
Because I don’t want to start flame wars about using (or not using, or abusing) Unit of Work, I try to be as neutral as possible in this matter. If you want Unit of Work, it’s OK for me, but please be as kind to remove Save methods from repositories. And if you don’t know if you wan’t to use Unit of Work or not, think if there is a chance that one of the repositories will ever be implemented using anything else than your favourite ORM (which is of course NHibernate). If so, don’t use Unit of Work because it’s abstraction will break on this one repository and so will your whole beautiful architecture.
The last line is, again, pretty obvious. Repositories are part of the Domain Model so, despite the fact they are not going to be used by domain objects, they need to be put in the same assembly to maintain logical cohesion.
I hope you enjoyed my subjective view of Repository as a pattern in Domain-Drive Design. I can’t wait to hear your opinions.



