Dependency Injection Breaks Encapsulation

“DI IS EVIL” “DI Breaks encapsulation”… try again.

And we’re back at A) you keep making these claims but can never substantiate them with code examples or answer the question “Why?”

Have you actually read that article? It quite clearly demonstrates a “copy” program which is used to copy a file from one device to another. In the original implementation there was only one input device and one output device, so the copy program had all that device code within its internals. This means that the “copy” program is restricted to only being able to function with those devices. If you had actually read the article you would have seen the following text:

The article then goes on to describe how it is possible to remove all the device code from the “copy” program and place it into a series of separate classes, one for each device. All that each of these classes requires is a read() method and a write() method. The “copy” program does not know or care about which device it is working with, it simply uses whatever objects have been injected into it. This also means that it is possible to create and use classes for new devices without having to amend the “copy” program.

Note here that two device objects have to be injected into the “copy” program - an input device and an output device, and each of these objects can be supplied from a number of alternative classes.

This tells me that DI is appropriate in those circumstances where a dependency can be supplied from a collection of possible candidates. The choice of candidates is made outside the program so the program does not have to make the choice itself.

So if DI is appropriate when there are several candidates for a single dependency, it is logical to state that where there is only a single choice for a dependency, and not any alternatives, then DI is not appropriate.

Has the penny dropped yet?

There you go, misrepresenting the facts again. While I refused to supply a single answer to cover all three points, I did supply a separate answer to each point

This is so backwards I can’t do anything but laugh at you.

I disagree. Encapsulation was never meant to mean information hiding, so it is definitely possible to have encapsulation without information hiding. This also means that encapsulation is not broken if there is no information hiding.

And you’re still missing the point. You cannot know whether encapsulation has been broken or not if you don’t have information hiding. With information hiding you know there is no way that encapsulation was broken.

I’m still not sure what point you’re even trying to make. Yes they’re separate concepts, yes, you don’t understand why Information Hiding is important (Although I’m guessing it’s because your code doesn’t already use it and/or it’s not supported in PHP4)… but what does it matter here?

No, I won’t. My motto is “Nix Illegitimi Carborundum”

It is not about the number of objects, it is about dependencies, specifically when a single dependency can be supplied from multiple sources. In that “copy” program each of the input and output devices can be supplied from one of several candidates.

It clearly shows that where you have a single dependency which can be supplied from multiple sources then DI has definite advantages. Having a dependency which can only be supplied from a single source clearly does not fit this pattern

But it’s equally appropriate when you only use one specific class as the dependency.

If you disagree with that statement, please finish this sentence:

“When there is only one possible dependency implementation, DI is not appropriate because…”

and then

“and… [alternative] is more appropriate because…”

You do realise that by agreeing with me, an OO heretic, in a public forum, then you are opening yourself up to the same levels of abuse and personal attacks that I am forced to endure?

For you information I have recently come across a new article on the interweb thingy at http://davidscode.com/blog/2015/04/17/when-does-dependency-injection-become-an-anti-pattern/ this contains the following observation:

So he agrees with my notion that when DI is overused, or used incorrectly, it becomes an anti-pattern (which is OO-speak for “not good”).
He also agrees with my point about injecting a single dependency which never changes.

Because I shouldn’t have to provided code samples for every point that I make.

It seems you looked at one example of an appropriate use of DI and concluded that this was the only appropriate use of DI. It isn’t.

1 Like

I’m glad you find it so amusing. If I can make at least one person laugh each day then it gives some meaning to my existence.

Just because one person agrees with you doesn’t make you right… it just means his opinion is as wrong as yours. The author in question is very confused as well. You’re not supposed to use a DI container during unit tests and for their second point, if you’re injecting a service locator into a class being tested then you are also testing all the classes in the service locator (And the service locator as well). Imagine a service locator that had a database connection and was used by the class being tested. In this case, you’d have to have an active database connection with specific data to test the class. Most of the time this really is not what you want to do.

The problem with this approach, is that when a test fails you don’t know if it’s because of a bug in:

  • The class you’re testing
  • The service locator
  • One of the classes being retrieved from the service locator

This is clearly not a “unit” test as you’re testing more than one unit and why we inject mocks during unit tests.

You never substantiate your claims with anything. Code examples would be the simplest way to do this which is why I ask for them.

1 Like

No, you are. Encapsulation has nothing to do with information hiding. This sentiment is echoed in the following articles:

http://www.tonymarston.net/php-mysql/abstraction.txt
http://web.archive.org/web/20090505194203/http://homepage.mac.com/keithray/blog/2006/02/22/#EncapsulationHiding
http://c2.com/cgi/wiki?EncapsulationIsNotInformationHiding
http://stefanoricciardi.com/2009/12/06/encapsulation-and-information-hiding/
http://nat.truemesh.com/archives/000498.html

Did you even read my post? I was agreeing with you they are separate concepts. However, in java, php and most other OO languages you must use information hiding to enforce encapsulation. Did you see my example code or was it too complicated to understand?

Without information hiding, I cannot guarantee this will not break:

class Player {
	public $weapon;

	public function __construct(Weapon $weapon) {
		$this->weapon = $weapon;
	}

	public function shoot() {
		$this->weapon->fire();
	}

}

Because elsewhere in the code this might have happened:

$player->weapon = null;

Information hiding is the only way to guarantee that this has not happened.

… it was designed for those circumstances where a dependency can be supplied from a number of alternative sources.

This means that if the number of possible sources is greater than one then DI is appropriate, but if the number of sources will never be greater than one then DI is not appropriate.

So “…because I said so”. What a fantastic non-answer.

But that’s not a reason because it’s factually incorrect DI is one of many methods that allows one object to be visible to another, that is all. it wasn’t “designed for those circumstances where a dependency can be supplied from a number of alternative sources.” at all!

You still didn’t answer why an alternative is “more appropriate”.

Can you justify that statement? The original definition of DI carries more weight than the multiple redefinitions that have fallen out of the sky since then.

I disagree. Encapsulation has absolutely nothing to do with information hiding.