Mark Needham

Thoughts on Software Development

Archive for April, 2009

DDD: Only for complex projects?

with 8 comments

One of the things I find a bit confusing when it comes to Domain Driven Design is that some of the higher profile speakers/user group contributors on the subject have expressed the opinion that DDD is more suitable when we are dealing with complex projects.

I think this means complex in terms of the domain but I’ve certainly worked on some projects where we’ve been following certainly some of the ideas of DDD and have got some value out of doing so in domains which I wouldn’t say were particularly complex.

What is Domain Driven Design?

One of the quotes from Jimmy Nilsson’s QCon presentation was that ‘DDD is OO done well‘ and I think there are a lot of similarities between the ideas of OO and DDD – in fact I think DDD has ended up covering the ground that OO was initially intended to cover.

Having our code express the domain using its own language rather than the language of the technical solution seems like an approach that would be valuable in any type of project and my recent reading of Code Complete suggests that this is certainly an approach that was used before the term DDD was coined.

However, if we’re truly doing DDD then in theory we should be modeling our domain with the help of a subject matter/business expert but from the projects I’ve worked on we can very rarely get access to these people so the modeling becomes a best attempt based on the information we have rather than a collaborative effort.

I’m not sure whether it’s actually possible to get a truly ubiquitous language that’s used by everyone from the business through to the software team by taking this approach. We certainly have a language of sorts but maybe it’s not truly ubiquitous.

As Luis Abreu points out, I don’t think there is a precise definition of what DDD actually is but for me the essence of DDD is still the same as when I compared it with OO i.e. Domain Driven Design = Object Oriented Programming + Ubiquitous Language.

What that definition doesn’t cover is the organisational patterns we can use to allow our domain model to fit into and interact with other systems, and I think this is a part of DDD which I underestimated when I wrote my previous post.

It also doesn’t take into account the possibility of doing DDD in a non OO language – for example I’m sure it’s possible to follow a DDD approach when using a functional language.

The value in using a DDD approach

As I’ve written before, I think there is value in applying the patterns of DDD even if we aren’t using every single idea that comes from the book. The approach of using just the patterns has even been coined as DDD Lite.

DDD Lite sounds to me like a particular subset of DDD but I would be quite surprised to find a project which used every single idea from the book, so maybe every use of DDD is merely a subset of the whole idea.

I’m not sure which presenter it was, but at QCon London the idea that we can use DDD to drive out the simplicity of our domain was expressed.

I would agree with this and I also think the idea of creating a ubiquitous language is very useful when working in teams, even if the domain is not that complex, so that we can stop doing the costly translations between the different terminologies people may be using to refer to the same things in the domain.

The idea of striving to make concepts in our code explicit rather than implicit is another idea which I think works very well regardless of the complexity of the project. Being able to look at code and understand what is going on without having to know a whole lot of context is invaluable.

Finally the organisational patterns of DDD, as Dan North pointed out at QCon, are valuable even in a non DDD context. We may not always use the DDD terms for what we are doing but I’ve noticed that a lot of the ways we interact with other systems have a corresponding DDD pattern which will explain the benefits and drawbacks of that approach and where it will and won’t be appropriate.

In Summary

I know neither of the authors are writing off DDD for projects with less complex domains but I feel the value that the different ideas can give to most projects is sometimes not recognised.

What the book has done well is bring together some very useful ideas for allowing us to write business software and since this is what a lot of us are doing it’s definitely worth looking at where the ideas of DDD can be applied.

Written by Mark Needham

April 6th, 2009 at 7:21 pm

Coding: It’s all about the context

with 9 comments

I think one of the easiest things to do as a developer is to look at some code that you didn’t write and then start trashing it for all the supposed mistakes that the author has made that you wouldn’t have.

It’s certainly something I’ve been guilty of doing and probably will be again in the future.

Sometimes it’s justified but most of the time we lack the context for understanding why the code was written the way it was and therefore our criticism is not very useful to anyone.

I think the more projects that I work on the more I realise that there’s no single set of rules that we can apply in all contexts.

I think rules or principles do still have value but we shouldn’t rigidly stick to them, but be aware when there is more value in not following the rule and then go for it.

To give a simple example, one of the forms of good practice when using the NUnit testing framework is to minimise our use of the TestFixtureSetUp attribute and instead use SetUp so that the common bit of code is repeated before each test is run rather than one time before all the tests are run.

One time when we found it useful to break this rule is when writing tests for mapping code when there are a lot of different things to assert and only one method call to make.

Using our normal approach of keeping each test as it’s own little specification resulted in tests that were really difficult so we broke the rule and using an approach which resembles the context/spec approach to driving code.

Looking at that code without the context of what I’ve just described you would probably think that it’s terrible code and that we don’t know how to use the framework but in this case it actually made our lives easier so I think it’s fine to break the rule in this case.

Another example is passing booleans into methods – in general I think this is really bad practice but it actually helps to significantly simplify code when we pass them into HtmlHelpers so that it knows whether to render the read only version of a control or not.

I’m not sure who said that ‘if you rewrite a system that you didn’t write the first time you’ll probably make the same mistakes as the original team did’ but it’s certainly becoming more clear to me how this would be the case.

The conclusion I’m pretty much coming to is that it’s great to follow a set of practices, and doing so helps ensure that we are doing the right thing most of the time, but having the flexibility of thought to step away from that and try something different is very important.

Written by Mark Needham

April 5th, 2009 at 7:45 pm

Posted in Coding

Tagged with

Functional C#: The hole in the middle pattern

with 5 comments

While reading Real World Functional Programming I came across an interesting pattern that I have noticed in some code bases recently which I liked but didn’t know had been given a name!

The hole in the middle pattern, coined by Brian Hurt, shows a cool way of using higher order functions in order to reuse code in cases where the code typically looks something like this:

public void SomeServiceCall() 
{
	var serviceClient = CreateServiceClient();
 
	try 
	{
		serviceClient.MakeMethodCall();
	}
	catch(SomeServiceException someServiceException) 
	{
		// Handle exception
	}
	finally 
	{
		serviceClient.Close();
	}
}

The first and the third lines (initialisation and finalisation) are always the same but the service.MakeMethodCall() varies depending on which service we are using. The more services we have the more boring it gets writing out the same code over and over again.

In C# 3.0 we could reuse code in this situation by passing in a lambda expression which calls that method, allowing us to vary the important part of the method call while keeping the scaffolding the same.

public void SomeServiceCall(Action<TServiceClient> callService) 
{
	var serviceClient = CreateServiceClient();
 
	try 
	{
		callService(serviceClient);
	}
	catch(SomeServiceException someServiceException) 
	{
		// Handle exception
	}
	finally 
	{
		serviceClient.Close();
	}
}
SomeServiceCall(service => service.SomeMethodCall())

One of the things I’ve noticed with the ability to pass in functions to methods is that sometimes we end up making the code really difficult to read by doing so but when we’re dealing with services this seems to be one of the best and most obvious uses of Actions/Funcs in C# 3.0 and it leads to a more reusable and easy to understand API.

Written by Mark Needham

April 4th, 2009 at 11:41 am

Posted in .NET

Tagged with ,

TDD: Testing mapping code

with 4 comments

I’ve previously written about some of the aspects of the mapping efforts that we’ve done on recent projects and what we’ve found from our testing (or lack of) around this type of code is that somewhere along the line you are going to have to check that you’re mapping these values correctly, be it in an automated test or just by manually checking that the correct values are being sent across our integration points and into other systems.

Writing unit tests around mapping code is certainly one of the areas of testing where it feels like there isn’t that much value in doing so – after all we are just copying data from one data structure to another, what could possibly go wrong?!

While I would certainly agree that in this case we are not using the tests to drive the design of our code, I think they are still very valuable for helping us to ensure that our specific bit of mapping code is doing what we expect it to.

Let’s say we have data flowing across our application like so:

test_your_mapping.gif

We get the data from the UI and we need it to end up being sent to the service. Along the way there are a few different places where data could get lost and from (painful) experience I’ve found that if we aren’t testing that all our data is being mapped then we will forget to map something and then we will have the fun job of debugging end to end trying to work out where it got lost.

I would certainly relax the notion of taking small steps a bit when doing this type of testing otherwise it can get immensely frustrating – maybe write the tests for a set of similar fields and then writing the mapping code rather than creating the test -> code cycle individually for each one.

These tests can end up getting quite difficult to read so an approach we’ve been trying is to setup the test data in a TestFixtureSetUp at the top of our NUnit test fixture and then creating just the assertions for similar sets of fields in each test. I think it’s working reasonably well even though maybe it goes against the convention of the way you would typically use NUnit.

We’re still got higher level tests around this code and while they’re useful they don’t help us zoom into the point of error that easily so the humble unit test still has a part to play!

Written by Mark Needham

April 2nd, 2009 at 11:11 pm

Posted in Testing

Tagged with ,