Thursday, March 1, 2007

DDD Examples

I like DDD. I think the idea that you can express business rules in software in the same terms you use to speak to your customers about their business is wonderful. It seems like a really natural place to go with object oriented design. Eric Evans and Jimmy Nilsson have helped a lot with their books on the subjects. But it can be really confusing for a newbie, especially one like me who wants to see concrete examples of how others have answered questions about how to express these business rules in the best way.

There was a discussion recently on the Domain Driven Design YahooGroup mailing list between Joe Reddy and Frans Bouma that I think encapsultes the issue:

> The developers at my office and I read Evans' DDD book and everyone liked the
> concepts. However we often disagree on implementation. Even within the same
> office we have different pressures, different environments and different
> priorities. These things rarely if ever change our thoughts on the DDD
> concepts; however they always change our thoughts on implementation.what the
> code looks like.
> So when people ask for code to show them how DDD is implemented I am also wary
> of supplying this to them.
> For example, my current team is developing in C# and we have no third party
> O/R mapping tool like I hear often discussed. Any code example with an> implementation of N/Hibernate means little to me.
> With that being said, we are all geeks and sometimes reading code can help
> lead us to some "Ah ha!" moments.

I think some fundamental problems are often ignored and people runinto them sooner or later.

Take for example Microsoft's example database called Northwind. In theentity model, there is obviously a problem, when you want to create aggregate roots and repositories:

Order references Customer
Order references Employee
OrderDetail references Order
OrderDetail references Product
Product references Supplier

Which aggregate roots and which repositories are the best for this situation? before people step in and say: this or that, be aware that there's no real parent/child situation here, except perhaps 'orderdetails' inside order, however orderdetails refers to product, which means the product thus also becomes part of the order aggregate, UNLESS you want to refer to orderdetails from TWO different aggregates (order and product), which can be cumbersome.

If you take a step back and think about this for a while you IMHO will come to the conclusion that the introduction of aggregates and repositories brought this problem onto the table, i.o.w.: it's a side effect of using these abstractions. However, without a proper set of rules-of-thumb, what should theaverage DDD user do to solve these problems? I think THAT's what the people who are asking for examples are after: to see how in real-life situations these things are solved, so they can apply the same solution to their own situation as well.

Tuesday, February 27, 2007

NHibernate reference app

Billy McCafferty has created a really nice NHibernate sample app on CodeProject using good ol’ Northwind. If you’re interested in NHibernate, you ought to take a look at it. Billy watches user comments on the article, and gives good help with questions.

His project shows a really nice example of using NHibernate.Generics, and creates a many-to-many bidirectional relationship between Customer and Order. I was interested in extending his domain just to play around a bit, so I decided to create an OrderDetail class. Specifically, I wanted to create a one-to-many one-way relationship from Order to OrderDetail – in other words, I just want the Order to keep track of its own OrderDetails, and I don’t think I really care about being able to see the Order from an OrderDetail. In order to get that working, I had to do the following:

1) Change the OrderDetails table definition in Northwind to include an integer field called OrderDetailID, and make that field the primary key.

2) Create an OrderDetail class like so:

using System;
using NHibernate.Generics;

namespace NHibernateSample.Core.Domain
public class OrderDetail : DomainObject
public OrderDetail()

public int ProductId
get { return productId; }
set { productId = value; }

public decimal UnitPrice
get { return unitPrice; }
set { unitPrice = value; }

public int Quantity
get { return quantity; }
set { quantity = value; }

public float Discount
get { return discount; }
set { discount = value; }

private int productId;
private decimal unitPrice;
private int quantity;
private float discount;


3) Add an OrderDetails collection to the Order class:

public IList<OrderDetail> OrderDetails
get { return _orderDetails; }

private EntityList<OrderDetail> _orderDetails = new EntityList<OrderDetail>();

4) And then map everything:
---- order.hbm.xml ----

<bag name="OrderDetails" lazy="true" table="OrderDetails" inverse="false"
access="NHibernate.Generics.GenericAccessor, NHibernate.Generics" >
<key column="OrderID" />
<one-to-many class="NHibernateSample.Core.Domain.OrderDetail, NHibernateSample.Core" />

---- orderdetail.hbm.xml ----

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="NHibernateSample.Core.Domain.OrderDetail, NHibernateSample.Core" table="OrderDetails">
<id name="ID" column="OrderDetailsID" unsaved-value="0">
<generator class="identity" />

<property name="ProductId" column="ProductID" />
<property name="UnitPrice" column="UnitPrice" />
<property name="Quantity" column="Quantity" />
<property name="Discount" column="Discount" />


One thing that threw me initially was the WireUpEntities() method he calls in the Customer and Order classes. Here's the one he has in the Customer class:

private void WireUpEntities() {
// Implement parent/child relationship add/remove scaffolding between Customer and Orders
_orders = new EntityList<Order>(
delegate(Order order) { order.OrderedBy = this; },
delegate(Order order) { order.OrderedBy = null; }

Since I’ve never used NHibernate generics, I apparently decided it would be a good idea to put my brain out to pasture for a little while, and not to actually dig in and understand what’s going on here before trying to use it for my OrderDetails collection. I tried some goofy similar stuff in the OrderDetails class, but it turns out that this code is for enforcing the bi-directional relationship – not needed at all for one-way relationships, I can just relax and let NHibernate do the work for me. The only difference is that I have to do this in my Order class:

private EntityList<OrderDetail> _orderDetails = new EntityList<OrderDetail>();

instead of this:

private EntityList<OrderDetail> _orderDetails;

In the bi-directional relationship between Customer and Order, WireUpEntities() instantiates the EntityList, but since you don’t need WireUpEntities() for one-way relationships you have to instantiate the EntityList yourself. NHibernate will only work with an existing won't initialize _orderDetails to a new EntityList itself. So if you don't call "new" in a wire-up method, then it needs to be done when declaring the member.

Thursday, February 22, 2007

Reference App for lots of cool stuff

I want to create a .NET reference app to be made available on CodeProject (or some other such site) which will demonstrate the following:
  1. Test Driven Development - full set of unit, integration, and acceptance tests
  2. Domain Driven Design - entities, value objects, services, aggregates, repositories, the works
  3. ORM using NHibernate - I want to explore issues that arise using DDD repositories with an EntityDataGateway to control the NHibernate session.
  4. MVP (maybe MonoRail)
  5. Continuous Integration - set of build scripts to build, test, and report on coverage.

Does a publicly available reference project that covers all these areas currently exist?

Tuesday, February 20, 2007

Random Rules Monday, Except That It's Actually Tuesday

Like many of the developers I've worked with over the years, I listen to music while I work. The Onion AV Club has a semi-regular feature called Random Rules where they get a celebrity to hit shuffle on their iPod, and then reveal all the embarrasing details that come up in the first ten selections. Here's mine for today:

  1. Just Another Night, Ian Hunter
  2. Road, Nick Drake
  3. A Star Is Bored, Paul Westerberg
  4. Mandolin Wind, Rod Stewart
  5. Beat on the Brat, The Ramones
  6. Wild Wild Lover, Flat Duo Jets
  7. Walkin' to My Baby, Fabulous Thunderbirds
  8. To Here Knows When, My Bloody Valentine
  9. Stiff Competition, Cheap Trick
  10. Vaseline, Elastica

Glad all the ABBA stuff didn't come up.

Monday, February 19, 2007

A test-driven chocolate cake?

Are there disciplines other than software development that implement something like Test Driven Development? And how effective would this approach be in other disciplines?

  • Can I know before my cake batter is ever mixed up what my cake is going to taste like?
  • Can I know before my dress design hits the runway that Milan will be absolutely beside itself?
  • And it would be really nice next season when hemlines rise or fall to be able to change the hem without worrying about whether or not you were going to pop another seam and ruin the whole dress.
  • Can I know before I cut my ear off and send it to a woman in an act of rage and desparation, and eventually take my own life in a lonely wheat field, that my paintings will one day be considered among the best ever created?
  • etc.

It would be really nice to know ahead of time that things are going to turn out ok, or at least like you planned them. We can achieve a measure of that in software development with discipline. And using a solid infrastructure of tests, we can have the confidence to make changes to our applications as the business demands it.

But how do other disciplines do it? We've been making things since the dawn of history. How have we historically tackled the problem of quality assurance?

Sunday, February 18, 2007

Jeff Atwood is filled with poo

Jeff Atwood sez programmers are born, that you can't become a great programmer if you aren't born one. He asserts that, "A mediocre developer can program his or her heart out for four years, but that won't magically transform them into a good developer." To Mr. Atwood, I offer this humble rebuttal (quoting Col. Potter): Monkey muffins! I'm not being fair to Jeff, after all a text without a context is a pretext. But it's my blog and I'll cry if I want to.

No one comes into this world knowing how to do anything except cry, poop, eat, and sleep. However, our Creator graciously endows some with talents for various things: there are those who are naturally bent towards music, others who can see an object and render an image of it on the page, still others who can work their way through the abstract logical problems we encounter in programming, etc, etc. Talent is raw material, useless without honing it into skill. Redmond wasn't built in a day: show me one application that has shipped in the history of computing that was entirely produced by a newbie approaching a keyboard (or a breadboard for that matter) for the first time.

Peter Norvig has a great little article about the determination it takes to build skill in any discipline:

Good stuff.