Sprint Planner Helper – Session 17

· March 5, 2009

When you learning something new you’ll expect some progress and the occasional setback. If you are on your own, as I am in this project, that is even more likely to be the other way around.

My approach to learning this is very much like the way we played with the chemistry box when we were small – try something you believe will work and expect the whole thing to blow up, possibly with a stinging sensation to your eye…

So… I guess that you see where this is going. I have to redo something. Actually it’s two. And actually I am not that worried; the whole idea of agile TDD, DDD and all this is that it should be easy to change.

The first thing is not biggie; my Entities has a Guid as ID right now. It’s mega-ugly when I am passing it around on the querystring etc. I’ll change that into an integer. The nice thing about Guid’s is that they are guaranteed to be unique. But not very human friendly…

The second thing is a more delicate matter in DDD. It has to do with aggregates and something called aggregate boundaries (which I understand as: “where do I stop, the whole database is knitted together…”).  This post, by Casey Charlton, explains the background in a nice, compact way. Actually the whole site rocks, with a the relevant posts as a book even.

For me Jimmy Nilsson summed it up in a nice way:

The parts of an aggregate have no reason to exists without their parent.

In my case I have the Product-class that contains a ProductBacklog which is a list of ProductBacklogItems. The ProductBacklogItems have no reason to exists without being attached to the Product. So the Product is my aggregate root.

And as far as I understand (here comes the chemistry box part :)) it should be no ProductBacklogItem-repository. Add how to add a ProductBacklogItem to the ProductBacklog should be an operation on the ProductBacklog.

When the whole Product (aggregate root) is saved the repository will have to save all parts of the aggregate. Which can be quite tricky in the update-case I presume, if the aggregate is big…

Seems like I will be learning how tricky in a while. On to the code!

[Some time passes by while Marcus is coding…]

Eeeh – that took much longer than anticipated and I will stretch this session over two sessions. The main reason for that is that was forced to invent some kind of auto-increment functionality for my fake repository. It was quite simple when I had it figured out. I simply rewrote the add method into this:

public void Add(T entity) { if (entity.ID == BaseEntity.NEWID) { // get the new highest id entity.ID = FindAll().Max(x =\> x.ID) + 1; }   dictionary.Add(entity.ID, entity); } </div>

But I still have the Update-functionality for my Product aggregate to figure out. More simple tests, please.

[Again some typing, head scratching and thinking takes place…]

Ok – that was much easier than I thought – which of course have to do with that I have a in-memory implementation of the repository right now… So the very simple Update-method:

public void Update(T entity) { dictionary\[entity.ID\] = entity; } </div>

… took care of it for me. It will probably be a bit more advanced when I have to map this to a relational database.

OK – but now I can create new product backlog items.

Great progress today – I’ve learned a lot about DDD today.

Twitter, Facebook