Tuesday, October 28, 2008

DDD - Making meaningful relationships

A recent discussion on the DDD forum made me want to post about what I consider to be an under-appreciated aspect of domain modelling, namely relationships. In the thread Randy Stafford said the following:

Note that RoleRegistration is an example of a Relationship Object – arguably a fourth archetype of domain object alongside Entity, Value Object, and Aggregate.

I couldn't agree more with this, in a domain model I worked on recently we had a stack of very useful and very meaningful relationship objects that served a range of purposes.

For example if a Client has Accounts then it is possible that you can get away with just having that as a direct relationship but its equally possible that the relationship itself is meaningful and carries its own data/behavior. In this case you might have a type association with the relationship that would explain if the Client owns the Account, or whethery just manage it, or whether they are actually just one of several owners.

Aggregates

You need to consider aggregate boundaries especially carefully when using Relationship Objects.

In the case of an association between a Client and an Account the relationship probably belongs to the Client aggregate.

Then again if you choose to model the association between a Client and SalesAdvisor using a full blown party/role/relationship approach then things become a big more complex. Are all parties and roles and relationships different aggregates or does a relationship own the two roles it composes?

If its the latter then you may be breaking an aggregate design rule because the party now refers to a piece of the relationship aggregate other than root.

Temporal Associations

Another common case is that the relationship is temporal which brings with it a lot of complexity and should only be done with extreme care.  If your sure you need temporal associations then you will find Martin Fowlers patterns invaluable.

Encapsulating Relationships

Most of the relationships have real meaning in their own right but sometimes they are just an artifact of the design, in those cases you can demote the associations to being just an encapsulated detail.

Take the association between Client and Account, maybe when you ask for the Accounts for a Client you want to get the Account objects rather than the ClientAccountRelationship objects.

If this were the case you could keep the ClientAccountRelationship class, which has its own data/behaviour and makes mapping easier, but entirely hide it from users of the domain. One way to do this is to create custom collection called ClientAccounts and have it wrap an IList<ClientAccountRelationship> whilst acting like it is just a simple IList<Account>, it can also provide helpful methods like FindPrimaryOwner.

Summary

I mention all of this because when I got started with DDD relationship objects bothered me especially as we were working with a legacy database and I saw the relationship objects as being a problem caused by the number of join tables. At the time my plan was to get rid of a lot of them by taking advantage of NHibernate magic.

However as I got a bit more experience I realized that they were key and although we encapsulated some (when they were just an artifact of the design) we made others totally key parts of the design. In both cases the relationships themselves were very useful.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Domain Driven Design - Knowledge Level

A recent thread on the ALT.NET forum got me thinking about KNOWLEDGE LEVEL, a seldom discussed but useful pattern from domain driven design. As with many patterns near the end of the book its a pattern that isn't going to suit every situation but it is a pattern that I think has a lot of value. In summary we aim to explicitly split our model into:

  1. Operations Level - The place that we do our day-to-day business. For example Shipment, Account.
  2. Knowledge Level - Objects that describe/constrain the objects in the basic (operations) level. For example EmployeeType, RebatePaymentMethod, ShipmentMethod.

I'm not a big fan of just repeating what's already in books and to my mind if you want to understand DDD then I'd suggest you read the DDD bible. I'm thus not going to go over the pattern, but I did think it was worth a post about what I've found when coming to the detailed design and implementation of classes in a knowledge layer. I thought I'd start by discussing how you can persist/load/model objects in the KNOWLEDGE LEVEL, moving on to other topics in later posts. Two caveats:

  1. Simple Example - Rather than using a real example I've chosen to use the shipping method example from the thread, I've never worked in that domain so this may be a bad idea but it felt right...
  2. Might seem obvious - If you are an object/behaviour first type of developer then you'll be looking at using OO techniques and so some of this will just be waffle. However I've seen situations where people used data-driven techniques when approaching their KNOWLEDGE LEVEL and so I wanted to explain why I think it's a bad idea.


Option 1 - Data First Approach

Since we store our operational objects in the database why not do the same for our KNOWLEDGE LEVEL? If we go down this path then we'd have a ShippingMethod table with one row for each shipping method we support. Of course each shipping method has different characteristics, perhaps certain shipping methods are only available to long standing customers or customers in certain countries. To support this we'll end up with extra columns in the ShippingMethod table and maybe even associations to other tables. To get the ShippingMethods from the database we'd probably use a REPOSITORY, probably making sure that the REPOSITORY is read-only (maybe not always, see pattern for information on modifying the KNOWLEDGE LEVEL).

Disadvantages

This approach obviously has disadvantages:

  1. Loss of clarity - Our ubiquitous language might refer to a "local carrier shipping method" but it won't be visible in the domain model and in fact to see details about this shipping method you need to look at the appropriate row in the ShippingMethod table. Even if you don't value the ubiquitous language this is a problem because as a developer you'll end up switching between the code and database in order to understand even simple aspects of the behaviour.
  2. Goodbye OO, hello procedural - Since there is no LocalCarrierShippingMethod class I have nowhere to put its behaviour, instead I have to fall back on a procedural style of program where we load in the data about the ShippingMethod with an ID of 3 (which happens to be the local carrier shipping method) and then look at its SupportsInternationalDelivery boolean flag before deciding how to proceed (hopelessly naive example alert). We can encapsulate this logic in a service, perhaps a ShippingMethodSelectionService but its still more than a little smelly.
  3. No explicit associations - Imagine if we know that the local carrier shipping method is only available for certain types of Orders and that the decision making also takes into account the Customer placing the Order. If we're using the database-driven approach then managing this becomes very difficult, we can't just look at our LocalCarrierShippingMethod class or at some code that sets up the associations. Instead we fall back and run a database query involving all sorts of joins.

Advantages

Those are, as I see it, the primary disadvantages of hiding this important information in the database. Ofcourse its not all bad:

  1. Consistency - Our KNOWLEDGE LEVEL is handled in the same was the rest of the domain model, loaded from the database as required. Not sure its a massive advantage though because we've explicitly chosen break out the KNOWLEDGE LEVEL its fair enough to say that the consistency has limited value.
  2. Flexibility - If we want to add a new kind of ShippingMethod we just add a row to the ShippingMethod table, no need to redeploy. That's the idea anyway, but its not always going to work especially when the related procedural code has to change.

Its also fair to say that the KNOWLEDGE LEVEL changes at a different pace to the rest of the model, we probably don't add ShippingMethods too often. However we might want to be able to change characteristics of existing ShipmentMethod's, such as changing their price (remember this probably only affects future Shipments) or changing what Countries they can be used in. So on the flexibility angle you've actually got a couple of types of changes:

  1. Adding/removing concepts -  Perhaps adding a donkey based shipment method, to me its safe to require a redeploy for this sort of change and in any case without some serious thought we're not necessarily going to be able to do just by modifying a table anyway. 
  2. Changing configuration/associations - Its maybe fair enough to expect to be able to ban using donkey based shipping for all future orders in Spain without requiring the code to be redeployed. As I'll show below this can work even if you go for an object-oriented approach and I also think this is a case where a DSL would really add value (not tried that though).

Those are the main advantages I've heard about, and as I say I'm not sold on them. That brings me on to how I think you should go about it...

 

Option 2 - Object Oriented Approach

Take that "local carrier shipping method" concept and turn it into a LocalCarrierShippingMethod class, probably inheriting from a ShippingMethod base class. There's only one instance of this class and since its read-only (at least as far as normal usage goes) it's totally safe to share it. The ShippingMethod has any data it needs to support the behaviour it contains and to support the interface that it exposes, so for example you might have an IsApplicableForSending(Shipment) with each subclass providing their own implementation.

Implementation

How does this look in practice, well one approach I've used is to a variant of the typesafe enum pattern. The following is just pseudo code to show the idea:

public abstract class ShipmentMethod
{
private static Dictionary<ShipmentMethodKind, ShipmentMethod> _shippingMethods = new Dictionary<ShipmentMethodKind, ShipmentMethod>();

static ShipmentMethod()
{
// NOTE: In practice you wouldn't do it like this but it is just an example....
_shippingMethods.Add(ShipmentMethodKind.LocalCarrier, new LocalCarrierShippingMethod());
_shippingMethods.Add(ShipmentMethodKind.DonkeyBased, new DonkeyBasedShippingMethod());
}

public IEnumerable<ShipmentMethod> GetAll()
{
return _shippingMethods.Values;
}

public ShipmentMethod GetByKey(ShipmentMethodKind key)
{
return _shippingMethods[key];
}

public abstract bool IsApplicableFor(Shipment toEvaluate);
}

public enum ShipmentMethodKind
{
LocalCarrier = 0,
DonkeyBased = 1
}

public class LocalCarrierShippingMethod : ShipmentMethod
{
public override bool IsApplicableFor(Shipment toEvaluate)
{

Don't get too hung up on the implementation, some of it is optional (e.g. ShipmentMethodKind) and it could be refractored quite a bit, I'm really just trying to show the idea not to show how to actually implement a solution.

You can see that in this case ShipmentMethod is really just a SPECIFICATION but in real situations a ShipmentMethod might well have more behaviour and data. The base class gives us an easy way to access all the ShipmentMethods that the system handles, this can be useful because it could easy provide useful methods like GetAllShipmentMethodsThatCanHandle(Shipment).

In reality there are multiple ways of implementing this, in particular you might want to load in the configuration for each ShipmentMethod from a database or other data source. This is more flexible than including it in the code but slightly more complicated to implement.

Referential Integrity

If you choose not to load the data from the database then we might seem to have a problem, how do we associate this ShipmentMethod with other objects in the KNOWLEDGE LEVEL and operational level?

It would seem that we've lost referential integrity but we have choices:

  1. Generate tables - The code in the static constructor in ShipmentMethod can be used to generate a table in the database.
  2. Use enum value as key - We can instead treat the value of the ShipmentMethodKind as a "key" in the database, automated tests will make spotting any issues really quick.
  3. Have separate config table - As I said earlier we may want to load the configuration information for each ShipmentMethod from the database, if so we have a ShipmentMethod table which resolves the problem.

In any case I haven't found this to be a major issue, by and large I don't care that my ShipmentTable has a ShipmentMethodId table which doesn't lead me anywhere as if I want to understand what's going on I go back to the domain model.


In Closing

Not sure this topic needed as much details I've put in here, really its the KNOWLEDGE LEVEL pattern that's key but I hoped that by enumerating some of the implementation choices that I've seen I'd help you make an informed decision.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Biztalk and WCF - When two big beasts collide

I spent the entirety of last week trying to create a ridiculously simple Biztalk orchestration and trying to get it to talk to a simple WCF service and I thought I should describe what I "learned".

Biztalk

If you follow me on Twitter you'll know how unbelievably annoyed the results made me and although I didn't learn much from the experience I thought I should put down some tips:

  1. If Biztalk gives you an error DO NOT read it, the message itself is bound to be utter jibberish and the correct response is to put it straight into Google.
  2. If Biztalk behaves like a problem is with step N don't assume that step N-1 passed especially if step N-1 is a transformation. You can test the transformation in isolation within the IDE using a sample document so do it,
  3. If you are having real problems working out why Biztalk and WCF aren't playing ball then it might well be XML namespaces that are the issue.
  4. If you're thinking of renaming the orchestration or anything in it be careful and take a backup first.

WCF

Whilst Biztalk left me cold the WCF side of it was a joy, mainly because Johnny Hall pointed me at the Castle WCF Facility and his own usages of it. Using the WCF Facility configuring your services is an utter joy, definitely when compared to the XML based approach that you get with bog-standard WCF. The documentation isn't great but the tests that you get with the Castle source code are the real way to see how to use its fluent interface.

Johnny also suggested we use a console application to host the service when testing and a Windows Service when deploying for a real. The console application makes testing locally a lot easier, just CTRL+F5 and your host is loaded and ready for you to fire requests at it.

If only Biztalk was as enjoyable to use...

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

BDD - Files/Folders/Namespaces (BDD)

Files/Folders
One thing that can be troublesome when moving from TDD to BDD is how to organize your files and folders, so far I've tried two approaches:

  1. One class in each file - So if you have When_associating_an_order_with_a_customer and When_associating_an_order_with_a_preferred_customer then they'd be in seperate files even though they are very closely related. If they share a base class, or a class they both compose, then that would be in yet another class (presumably).
  2. Multiple classes per file - As an example you might group the Order addition contexts into a file called OrderPlacementSpecifications, the file could also contain the shared base class (if you went down that road).
To me the second approach has a couple of advantages:
  1. Gives the reader extra information - By grouping the two order placement classes we tell the reader that they are quite closely related.
  2. Simplifies folder structure - If we go for the other approach, one class in each file, then we're probably going to have to have more folders. The addition of the extra files and folders definitely makes the solution file harder to structure.
To give you an idea here's a screen shot of a part of the folder structure for a sample app we're doing:

Namespaces
In addition to files/folders I've tried a few approaches to structuring namespaces but the approach I'm trying now groups related artifacts. For example:
  1. Specifications.Users.Domain
  2. Specifications.Users.Domain.Contacts
  3. Specifications.Users.Services
  4. Specifications.Users.Domain.Repositories
  5. Specifications.Users.UI.Controllers
The "Specifications" bit adds very little but I think grouping all specifications related to users is useful, not least as R# makes it easy to run all the specifications in a namespace. This can be useful if you have a big solution and only want to run the specifications for the area your working on. Its also worth saying that its "Users" to avoid clashing with the "User" class.

Folder wise however we're using a standard approach where your Repositories are in a completely seperate folder from your controllers, even though they might both relate to a particular entity. To me the lack of relationship between our folders and namespaces isn't a problem though, with R# its easy to find a file/type and in addition the folder/namespace tell you two different things about your codebase (one by "layer", one by "feature").

So I'm interested in peoples views? I'm guessing you'll all dislike it though because from what I've seen no matter what you do people will be unhappy with your file/folder/namespace scheme. Pluse we'll probably turn against this approach next week....

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Thursday, October 23, 2008

What I want from an ORM

Thought I'd blog about some of the things I'd like to see in an ORM in the future, particularly to support DDD cleanly:

  1. No enforced associations - I never want to create an association in the model just to support persistence, regardless of where keys are stored. So if I want to use uni-directional associations then I should be able to do that without having to go for workarounds.
  2. Aggregate locking - Currently, with NHibernate at least, its difficult to lock an entire aggregate. For example NHibernate's optimistic concurrency approach involves applying a version to rows, however aggregates can span tables so we really want to be able to give each aggregate a shared version (coarse-grained locking approach). See coarse-grained lock pattern.
  3. Validating before saving - I'd like hooks to automatically and cleanly validate an entire aggregate before persistence.
  4. Disabling unit of work - I'd like to be able to disable my unit of work, in many cases when working with DDD the UOW becomes more of a hindrance than anything else. I really want to be 100% sure that the only way to save a Customer is through a CustomerRepository.
  5. Revalidate value objects when reloading - Value objects only validate their data in their constructors, if your ORM does not ensure that a constructor that performs the validation is also used when reloading the object then its possible to end up with an invalid Value object. This is something you definitely want to avoid. Greg Young has raised this issue a few times, including in the NHibernate forum, and made some very good points.
  6. Value objects - Choosing to view something as a value object is a design decision that you make irrespective of the underlying DB design, so whilst the NHibernate component mapping is useful it should be as powerful as the mappings used elsewhere. Unfortunately with NHibernate components don't support inheritance nicely and if your value object is stored in a separate table things get confusing.

There may be other things I'd want but those are the ones that come to mind.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

New Home

Just to let you know that I'll now also be posting over at lostechies. Obviously I'll continue to post everything here though so you only need to do anything if your already subscribed to the lostechies feed and getting my blog entries twice is annoying you.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Wednesday, October 22, 2008

DDD and Complexity

There have been some interesting and entirely valid discussions on Twitter about the validity of DDD and about deciding when its useful and when its too complex (including good comments from Casey Charlton and Jimmy Bogard). I full agree with Casey and Jimmy and the comments, when combined with an interesting discussion on the topic at the latest ALT.NET UK discussion, let me wanting to blog about how I think DDD can be used in different types of projects.

First off I must admit that even for a simple business system I'd be thinking about using some of the patterns from DDD, in particular I think these usually have value:

  1. Aggregate
  2. Repository
  3. Service

For example I find that thinking about aggregates makes me think much more carefully about how to map those classes to the database, for example how far to cascade, which in my view is a good idea as not thinking about boundaries can lead you to some fairly annoying debugging sessions. You can take these three patterns and with a good ORM and create and map a simple domain model to a green fields database very quickly. 

Tradeoffs

Here's some of the tradeoffs we're making when using DDD on a system that it doesn't necessarily suit:

  1. Analysis/Design - We map completely skip the analysis/design and in particular the discussions with the domain expert, instead starting from our requirements and letting TDD and our own design skills guides us to the correct design.
  2. Encapsulation - We might expose everything using getters and setters and the domain may be anaemic, for example validation may be in attributes and/or use a custom framework.
  3. Design Clarity - If our primary focus is on getting going fast then we're going to have to cut some corners.  We'd bind the domain to the GUI, design it to be as easy to map to the database, make it easy to create domain objects (default constructors) and generally make tradeoffs in the quality of the domain model to make our own lives easier.
  4. Flexibility - A model that is quick to create/map/bind is not likely going to be flexible, this may or may not be a problem.
  5. Patterns - We're ignoring half the patterns in DDD, patterns that have a lot of value in a complex domain model but may not be justified when the domain is simpler/more closely bounded.

We make these tradeoffs to make our lives easier and in particular I wanted to cover two of the tradeoffs you may choose to make.

Design Clarity

If we want to be able to bind your GUI to the domain and map it to the database quickly then we can being to fray our domain model:

  1. Value objects make binding and displaying validation errors trickier.
  2. If our user interface uses wizards then the GUI will want to create domain objects early on in the wizard, possibly without giving us any meaningful data. We thus end up with default constructors or constructors with very few arguments.
  3. If we use an ORM with a unit of work it will probably fight against our need to validate aggregates before saving them.
  4. If we use an ORM we'll find it hard to version the entire aggregate.

With discipline you can make these tradeoffs whilst still maintaining a comprehensible model but there is no doubt that we are making tradeoffs.

Flexibility

We're also sacrificing flexibility, for example a lot of talk about repositories right now focuses on generic repositories. For example we'd have a Repository<T> class where T is an aggregate root and you'd have query methods on this repository that would take Linq specifications. That's going to be fine for a lot of cases but in more complex models (or where we don't control our environment fully) our repository can encapsulate complex logic, for example we should be able to ensure the following:

  1. Instances of aggregate are never deleted or they are simply archived.
  2. Instances of aggregate Y are built up from multiple data sources.
  3. Instead of mapping aggregate Z to a (legacy) DB we map some simple DTO's and then in the repository convert them to our nicely designed aggregate.
  4. Query Z is very expensive and needs to be done using SQL.

Those are all things I’ve had to be involved in when working with a moderately complex domain model and repositories helped encapsulate those details. So whilst I think generic repositories might have their place ins some systems I think you have to be aware of the choices your making.

What was the point of all this?

My point with all this is that you can get a lot of value from DDD without following it too closely, but you need to be aware of what tradeoffs your making and why. Choosing to go for a simple domain model when you have a complex problem to solve is a really bad choice and going from active record (true active record) to a real domain model is not going to be a smooth transition.

However I don't think the choice is easy, for example there's been a lot of discussion recently on whether DDD and complex models are suitable for CRUD related problems. In general I can see why using DDD on an average CRUD system is a mistake but sometimes it is worth using. For example we used DDD on a CRM system that among other things handled parties and their associations in a temporal manner. This was a complex modelling problem solved with a complex pattern but primarily we were handling CRUD (including constraints/validation) and setting the stage for other systems to use the information. Trying to do this using active record would, in my view, have been a big mistake.

So as Casey pointed out DDD is expensive and whilst it can pay off you need to do in with eyes open fully aware of the tradeoffs involved.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Monday, October 20, 2008

ALT.NET Drinks in Edinburgh

We're "organizing" the first (and who knows, perhaps the last) ALT.NET drinks in Edinburgh on the 3rd of November (starting around 7:30). Its at a pub called the Rutland and if you're travelling over in the train its a conveniant spot (5-10 mins walk from Haymarket).

You can read more, though not a lot more, at the UK .NET events site and in the Glasgow ALT.NET thread.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Sunday, October 05, 2008

Book Review - Enterprise SOA

I just got through with Enterprise SOA and have to say I think itis well worth a read. If you want a good review look here but here's a summary of some of my favourite aspects of the book:

  1. Covered a range of technologies, emphasizing that SOA is not just about throwing out a range of Web services.
  2. Covered valid design/architecture choices, for example discussing asynchronous and synchronous approaches and where they might each be useful.
  3. Discussed how services can be a valuable tool in bringing IT/business closer together.
  4. The case studies were very interesting, I actually would have liked it if the book had more detail but what it did include was useful.
  5. The coverage of governance had me nodding my head, even if you don't chose to apply SOA you'll need to know how ensure that people don't fall back into tactical decision making.
  6. Covered how SOA can change your approach to project management.
  7. We need someone other than Erl talking about how to make SOA work in practice.

So I think the book is superb and well worth a read.

Having said that one issue I had with the book was the emphasis on having basic services as the cornerstone of your SOA (basic services being essentially entity services). I'm hoping that in a future edition the authors will explore how SOA can be used in a manner that work hand in hand with DDD and I think this would mean re-evaluating whether reusable entity services are really a good idea.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone