So far we have sketched out a pretty basic and primitive API for our Domain Model. Creating an order with two products could look like this (assuming we are already holding on to a specific customer):
Order newOrder = new Order(customer); OrderLine orderLine; orderLine = new OrderLine(productRepository.GetProduct("ABC")); orderLine.NumberOfUnits = 42; newOrder.AddOrderLine(orderLine); orderLine = new OrderLine(productRepository.GetProduct("XYZ")); orderLine.NumberOfUnits = 3; newOrder.AddOrderLine(orderLine);
I think it's pretty easy to follow. But it's a bit verbose and not as fluent as it could be. A simple way of shortening it would be to add numberOfUnits to the constructor of OrderLine, taking it down to three statements, like this:
Order newOrder = new Order(customer); newOrder.AddOrderLine(new OrderLine (42, productRepository.GetProduct("ABC"))); newOrder.AddOrderLine(new OrderLine (3, productRepository.GetProduct("XYZ")));
But it's still not very fluent. Martin Fowler's "FluentInterface" [Fowler FluentInterface] is good inspiration. Let's see if we can sketch the API to be a bit more fluent. Perhaps something like this:
Order newOrder = new Order(customer) .With(42, "ABC") .With(3, "XYZ");
It's both shorter and clearer. In my sketch, I kept the first line because I think that is pretty clear. Then the With() method takes the numberOfUnits as parameter and a product identification so that With() internally can use the productRepository for finding the product. (Let's assume for now that With() can find the productRepository at a well known place.)
With() also returns the order, and therefore we can chain several statements after each others.
Let's try out a variation. Assume that we can't create the whole order in one swoop, but want to add an orderLine as the result from a user action. Then we might prefer something like this for adding an orderLine:
newOrder.AddOrderLine("ABC").NumberOfUnits = 42;
This time AddOrderLine() returns the orderLine and not the order. We could take that further if we want to be able to set more values of the orderLine by changing NumberOfUnits into a method instead that returns the orderLine again, but you get the point.
The important thing to take away from this section is how much better your API can become if you play with it a bit.