Domain Driven Design Anti-Patterns

[Note: I was going to call this post How to Fail with Domain Driven Design, but that just sounded too pessimistic.]

I’ve been developing business applications on the Microsoft platform since the mid 1990s. The years since then have involved a continual process of learning to be more effective in architectural approach. Along the way, there have been key points where I made leaps forward. Two such examples include object-orientation in the 90s and my first Web service in 2000 (anyone remember SOAP Toolkit2?).

Each of these leaps forward also came with some initial stumbles as I grappled with the promising new approach. Pushing the envelope of productivity means trying new things. New things always create risk. Software is hard. The path of progress in software is never a straight line (unless you are creating commodity level software). However, stumbling when taking on new approaches can be minimized if you learn from other peoples mistakes instead if just your own.

Another big leap forward for me started with my reading of Domain Driven Design in 2005. Since that time, I have been putting DDD principles into practice. I have learned a lot-much of it by my own mistakes. What I offer here are some concrete examples of mistakes I made. I’ll show the mistake I made and how I later fixed it so you can compare and contrast the before and after. Sometimes I learn a pattern best by seeing examples of its anti-patterns. I hope these articles will help you create better software and add to the growing awareness of DDD.

  1. Not accounting for command and queries as separate concerns.
  2. Not getting the whole team educated on DDD early enough.
  3. Not taking bounded contexts seriously.
  4. Allowing implementation decisions to drive the domain model.

The above list will serve as the table of contents for the series. I’ll enable the links as I write the articles. I’ll probably add an article or two to the list as I go.

Free Your Data, and UIs are Free

This video describes how the Massachusetts Department of Transportation began publishing real-time bus arrival data and within two months there were six compelling applications available that harnessed that data.

Joshua Robins of the Massachusetts Department of Transportation

This shows that if you make your data available, there are legions of developers willing to build applications on various platforms. Massachusetts could have spent months building a lame Web site and then making the data available. By making the data available first, they didn’t need any UI at all.

It’s easy to see how this can work with public data. I believe this same principle works inside the enterprise. If we build our line of business applications to publish their data in open formats, anyone can build the applications that display that data to users in whatever formats users need.

HT: Jack van Hoof

Domain-Driven Design Friendly Persistence on the Compact Framework

I’ve been searching for a persistence tool that will eliminate the hand coding of our basic CRUD operations. I’m looking for something that allows us to develop our domain model in plain, unencumbered C# classes, and later persist them to a data store. Ideally, I’d like to use the same tool on both the Windows Mobile devices and on the server (just so we don’t have to learn two different tools or frameworks). This is the story of my pain…

NHibernate – The first and obvious choice for DDD-friendly persistence in .NET is NHibernate. It is a true object-first ORM and seems to have a lot of interesting tooling growing up around it. Alas, NHibernate is not supported on the Compact Framework because of some unsupported reflection it uses.

LLBLGen Pro – Developers who use LLBLGen Pro seem to love it. It is supported on the Compact Framework, but LLBLGen will not support an object-first approach until version 3.0 which won’t even beta until the end of Summer 2009, which is way too late for me.

Entity SpacesEntity Spaces is yet another commercial database-first ORM that runs on the Compact Framework. I don’t see anything that it offers that LLBLGen doesn’t offer.

Entity FrameworkEntity Framework is supported on the Compact Framework and is free but does not support any kind of POCO, object-first approach.

db4objectsdb4objects was an extremely intriguing option. I had never considered using an object database before. I found db4o extremely easy to use and intuitive—perfect for the lightweight storage needs we have on handheld devices. However, db4o is offered under a GPL or commercial license. The GPL license won’t work for us and the commercial license is orders of magnitude more expensive than a tool like LLBLGen or Entity Spaces.

Given that having our developers write all of the database access code by hand is (in my opinion) too time-consuming and error prone, I’m left facing some sort of compromise approach.

One option is to create my domain model as I need to, ignoring persistence. Then, within my repository implementation use a data-first tool, treating the “entities” generated by the persistence tool as DTOs and manually translate them into my true domain objects.

The second option is to again model the domain, but attempt to back into the code we need for those objects using a tool like EF or LLBLGen. The Patterns and Practices guys seem to think this approach is true to the DDD concept (see this article). I’m not sure I agree.

I think I’ll give a go at the second approach and fall back to the first if I see that the database schema, and not my domain, is driving the conceptual creation of my object model. I’ll also have to figure out whether to use LLBLGen or Entity Framework. EF is free, but LLBLGen is more mature and may offer a better option in the next version.

SOLID: What is Old is New Again

SOLID

Sometime around 2001, I came across a series of articles by Robert C. Martin. At that time they were already a little old—from The C++ Report in 1996. I didn’t really care. This guy (who I now know as everyone else does as “Uncle Bob”) had captured and expressed core principles that I knew from experience were the key to creating maintainable software. I mostly knew it mostly from having violated them and paying the price.

The principles put forth in those articles express fundamentals truths that are in play in any Object-Oriented software project.

In the fifth article in the series, Martin sums up the first four…

1. The Open Closed Principle. (OPC) January, 1996. This article discussed the notion that a software module that is designed to be reusable, maintainable and robust must be extensible without requiring change. Such modules can be created in C++ by using abstract classes. The algorithms embedded in those classes make use of pure virtual functions and can therefore be extended by deriving concrete classes that implement those pure virtual function in different ways. The net result is a set of functions written in abstract classes that can be reused in different detailed contexts and are not affected by changes to those contexts.

2. The Liskov Substitution Principle. (LSP) March, 1996. Sometimes known as “Design by Contract”. This principle describes a system of constraints for the use of public inheritance in C++. The principle says that any function which uses a base class must not be confused when a derived class is substituted for the base class. This article showed how difficult this principle is to conform to, and described some of the subtle traps that the software designer can get into that affect reusability and maintainability.

3. The Dependency Inversion Principle. (DIP) May, 1996. This principle describes the overall structure of a well designed object-oriented application. The principle states that the modules that implement high level policy should not depend upon the modules that implement low level details. Rather both high level policy and low level details should depend upon abstractions. When this principle is adhered to, both the high level policy modules, and the low level detail modules will be reusable and maintainable.

4. The Interface Segregation Principle. (ISP) Aug, 1996. This principle deals with the disadvantages of “fat” interfaces. Classes that have “fat” interfaces are classes whose interfaces are not cohesive. In other words, the interfaces of the class can be broken up into groups of member functions. Each group serves a different set of clients. Thus some clients use one group of member functions, and other clients use the other groups.

The ISP acknowledges that there are objects that require non-cohesive interfaces; however it suggests that clients should not know about them as a single class. Instead, clients should know about abstract base classes that have cohesive interfaces; and which are multiply inherited into the concrete class that describes the non-cohesive object.

Martin later published The Single Responsibility Principle, which says that there should never be more than one reason for a class to change.

There were several aspects of these short articles that helped me so much…

  • The articles were short but clear.
  • The articles were available on-line for anyone to download and read.
  • Martin gave these principles names.

All of these aspects made these principles easy to promote—and I did! I preached all of these principles, whether in C++ or later C#. So, I am particularly pleased to see the recent resurgence in these principles as the ALT.NET crowd has arranged them into a nice acronym (SOLID) and made back-to-basics cool again. We see the SOLID principles all over blogs and articles in the agile community. It reaffirms my belief that the fundamentals may go in and out of style, but they are always what matters most in good software development.

What is Architecture?

Architecture is one of those overloaded terms in the software industry that has been so abused that we should consider scrapping it and coming up with a new words to replace it. However, that isn’t going to happen anytime soon; so, we’ll have to try to recover this one.

I recently came across Grady Booch’s definition of architecture, and I really like it…

All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change. –Grady Booch

This succinctly captures what I think makes for good architectures and good architects. The best architects have good judgment and intuition, based on experience, about what the most important design decisions are. They recognize which aspects of a system they’ve got to get right from the start and which can be firmed up later. They focus on the design decisions that would be costly to change later.

Desktop Developer’s Introduction to Compact Framework Development: Part 1-Introduction

As I’ve made my transition from the Microsoft desktop platform (x86, Windows, .NET, C#, etc.) to the world of handheld devices (ARM, Windows CE, Windows Mobile, .NET CF, etc.), there have been a number of fairly basic things that I’ve had to learn the hard way. They are so basic to being productive in the compact world that there ought to be a brief guide to bring an experienced desktop developer up to speed in short order. I didn’t come across that; so, I intend to provide that here for the next guy (or gal) who comes this way.

I am not an expert on this stuff (yet) but I am immersed in getting up to speed on them. So, I will introduce the important topics and point you to resources that I found helpful for the details.

The sorts of things I plan (so far) to cover include topic like… What is CE and how does it relate to Windows Mobile? What is the memory model on CE? What are the memory limitations and strategies for working within and around them? What do you have to do to run your .NET code on the handheld device? How do you do unit testing with CF code? I’m also going to document a few potholes that initially slowed me down.

Just so this initial post is not completely devoid of actual value, I’ll start with the most basic thing you need to know. Most handheld devices are built on a flavor of RISC processor called ARM (or Advanced RISC Machine). You can get a good overview from Wikipedia and the company view from ARM itself. While the primary measure of desktop processors is speed and throughput, the primary concern in the handheld world is power consumption. You learn that pretty quickly.