tags:

views:

533

answers:

6

I have been adding dependency injection to my code because it makes by code much easier to Unit test through mocking.

However I am requiring objects higher up my call chain to have knowledge of objects further down the call chain.

Does this break the Law of Demeter? If so does it matter?

for example: a class A has a dependency on an interface B, The implementation of this interface to use is injected into the constructor of class A. Anyone wanting to use class A must now also have a reference to an implementation of B. And can call its methods directly meaning and has knowledge of its sub components (interface B)

Wikipedia says about the law of Demeter: "The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents)."

+1  A: 

Does it break the law?
Strictly speaking, I think it does.
Does it matter?
The main danger of breaking the law is that you make your code more brittle.
If you really keep it to just the tests, it seems like that danger is not too bad.
Mitigation
My understanding of the Law of Demeter is that it can be followed by having "wrapper methods" which prevent directly calling down into objects.

John Mulder
+1  A: 

How does it break it? DI perfectly fits in idea of least knowledge. DI gives you low coupling - objects are less defendant on each other.

Citing Wikipedia:

...an object A can request a service (call a method) of an object instance B, but object A cannot “reach through” object B to access yet another object...

Usually DI works exactly the same way, i.e. you use services provided by injected components. If your object try to access some of the B's dependencies i.e. it knows much about B - that's leads to high coupling and breaks idea of DI

However I am requiring objects higher up my call chain to have knowledge of objects further down the call chain

Some example?

aku
+2  A: 

If I understand you correctly, this isn't caused by the use of dependency injection, it's caused by using mocking strategies that have you specify the function calls you expect a method to make. That's perfectly acceptable in many situations, but obviously that means you have to know something about the method you're calling, if you've specified what you think it's supposed to do.

Writing good software requires balancing tradeoffs. As the implementation becomes more complete, it becomes more inconsistent. You have to decide what risks those inconsistencies create, and whether they're worth the value created by their presence.

David M. Karr
+7  A: 

Dependency Injection CAN break the Law of Demeter. If you force consumers to do the injection of the dependencies. This can be avoided through static factory methods, and DI frameworks.

You can have both by designing your objects in such a way that they require the dependencies be passed in, and at the same time having a mechanism for using them without explicit performing the injection (factory functions and DI frameworks).

Mark Roddy
I think you nailed it. Some of the other answers to this question aren't focusing on the asker's specific situation.
moffdub
+1  A: 

The Law of Demeter specifies that the method M of the object O can call methods on objects created/instantiated inside M. However, there's nothing that specifies how these objects were created. I think it's perfectly fine to use an intermediary object to create these, as long as that object's purpose in life is only that - creating other objects on your behalf. In this sense, DI does not break the Law of Demeter.

Franci Penov
A: 

Depends :-)

I think the top answer is not correct , even with a framework a lot of code uses Dependency injection and injects high level objects. You then get spaghetti code with lots of dependencies.

Dependency injection is best used for all the stuff that would pollute your object model eg an ILogger. If you do inject business object ensure its at the lowest level possible and try to pass it the traditional method if you can . Only use the dependecy injection if it gets to messy .

Benk