Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Many of the other answers hint at it, but I'm going to more explicitly say that yes, naive implementations of dependency injection <strong>can</strong> break encapsulation.</p> <p><strong>The key to avoiding this is that calling code should not directly instantiate the dependencies (if it doesn't care about them).</strong> This can be done in a number of ways. </p> <p>The simplest is simply have a default constructor that does the injecting with default values. As long as calling code is only using the default constructor you can change the dependencies behind the scenes without affecting calling code. </p> <p>This can start to get out of hand if your dependencies themselves have dependencies and so forth. At that point the Factory pattern could come into place (or you can use it from the get-go so that calling code is already using the factory). If you introduce the factory and don't want to break existing users of your code, you could always just call into the factory from your default constructor.</p> <p>Beyond that there's using Inversion of Control. I haven't used IoC enough to speak too much about it, but there's plenty of questions here on it as well as articles online that explain it much better than I could.</p> <p>If it should be truly encapsulated to where calling code <em>cannot</em> know about the dependencies then there's the option of either making the injecting (either the constructor with the dependency parameters or the setters) <code>internal</code> if the language supports it, or making them private and have your unit tests use something like Reflection if your language supports it. If you language supports neither then I suppose a possibility might be to have the class that calling code is instantiating a dummy class that just encapsulates the class the does the real work (I believe this is the Facade pattern, but I never remember the names correctly):</p> <pre><code>public Car { private RealCar _car; public constructor(){ _car = new RealCar(new Engine) }; public float getSpeed() { return _car.getSpeed(); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload