Law of Demeter: Nice metaphor

I just came across a nice metaphor for explaining the Law of Demeter. For those of you that didn't yet hear about it, the Law of Demeter is a object oriented design principle. A guideline basically which leads to nice and testable OO code, but Wiki will tell you more.

The metaphor is the following:
Imagine you are in a store and the item you are purchasing is $25.

Do you give the clerk $25?

Or do you give him the wallet and let him/her retrieve the $25?
Intuitive I guess :) . The same actually holds for the design of objects. Consider this example:
class Goods{
AccountReceivable ar;

void purchase(Customer customer){
Money m = customer.getWallet().getMoney();
ar.recordSale(this,m);
}

}

You still may not see the problem but it'll come out when testing the purchase method. For doing so the following code has to be instantiated:
class GoodsTest{

void purchaseTest(){
AccountReceivable ar = new MockAR();
Goods goods = new Goods(ar);
Money money = new Money(25, USD);
Wallet wallet = new Wallet(money);
Customer customer = new Customer(wallet);

//finally
g.purchase(customer);
assertEquals(25, ar.getSales());
}
}
Looks horrible, doesn't it?

Instead, when following the Law of Demeter, we would design it as follows:
class Goods{
AccountReceivable ar;

void purchase(Money money){
ar.recordSale(this,money);
}

}
and test it like
class GoodsTest{

void purchaseTest(){
AccountReceivable ar = new MockAR();
Goods goods = new Goods(ar);

g.purchase(new Money(25, USD));
assertEquals(25, ar.getSales());
}
}
Looks already much nicer and much more correct in my opinion. Why should the Goods class know where the money comes from?? It just shouldn't care about that.

In my eyes this is a really nice explanation of the Law of Demeter and moreover it shows how unit testing uncovers flaws in your code. When unit testing gets hard or impossible is a big indication of problems in your code. That's why a lot of people don't like unit testing...just because they're writing untestable code.

I've another draft post in my blog list about how you can improve testability and software design by using dependency injection. It's very tightly coupled to this topic here. I just did not yet find the time to finish it and btw...now I really have to continue to study for my Statistics exam this Friday...
Kindle

Comments

0

Your ad here?