10

Given that changes to the API/public method signature should be minimal to prevent breaking those client codes that use these methods, I was wondering if the Law of Demeter is less applicable to these.

A simple example:

class Account() {
   double balance;
   public void debit(Transaction t) {
      balance -= t.getAmount();
   }
}

Notice that the debit method passes the Transaction object rather than just double amount (the 'Law of Demeter', as I understand it, would say to just pass the required info, in this case just the amount, not the Transaction object...). The reason behind this, is because the method in the future might require some other Transaction properties aside from amount. From what I understand, this will prevent breaking the method signature by adding a new parameter in the future.

Does this make it a sensible choice then? Or am I missing something?

2 Answers 2

3

But this doesn't break the Law of Demeter.

More formally, the Law of Demeter for functions requires that a method M of an object O may only invoke the methods of the following kinds of objects:

  • O itself
  • M's parameters
  • any objects created/instantiated within M
  • O's direct component objects
  • a global variable, accessible by O, in the scope of M

Wikipedia: Law of Demeter

Transaction is an argument to the debit method, so calling t.getAmount() is fine.

Edit: Misread that, you are saying the LoD would have you pass the amount of the transaction, not a Transaction object. If that is the case then yes, I think this is a good place to break it, knowing you will need more from the Transaction object in the future. Also, encapsulating primitives in domain level objects is another good programming practice.

Edit 2: Having read the might need more in the future, one could also see this as unnecessary gold plating. Providing a method that takes a double now (or better a Money class) is sufficient. If you do need a Transaction argument later it's not disastrous to provide a second signature taking a Transaction, but continue to support the original signature. It's not like you would be implementing two methods, one would call the other.

2
  • Thanks for your input. I agree about the encapsulating primitives in domain objects. However, just your point in Edit 2, you say its not disastrous to add a new 2nd signature, but that would mean code change to client code that now should pass 2 parameters instead of one. That 2nd point, I'm abit hesitant to agreed on... Commented Mar 13, 2012 at 7:15
  • Edit 2 is subjective, I agree.
    – Sean
    Commented Mar 13, 2012 at 9:57
0

If you're planning on expanding the Account class in the future, I would say this is a situation where making the Transaction object more general purpose would be a good bending of the rules of the Law.

For example:

public class Amount {

    public void process( Transaction t ) {
        ....
    }
}

public abstract class Transaction {

    public String getType();

}

I think I'm kind of straying from the original question, but my point is that while you may be worried that you're straying from the Law of Demeter, the advantages of doing so outweigh the negatives.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.