Why should I use dependency injection?











up vote
51
down vote

favorite
16












I am having a hard time looking for resources on why should I use Dependency Injection. Most of the resources that I see explains that it just passes an instance of an object to another instance of an object but why? Is this just for cleaner architecture/code or does this affect performance as a whole?



Why should I do this:



class Profile {
public function deactivateProfile(Setting $setting)
{
$setting->isActive = false;
}
}


instead of this:



class Profile {
public function deactivateProfile()
{
$setting = new Setting();
$setting->isActive = false;
}
}








share


















  • 7




    You are introducing a hard-coded dependency to deactivateProfile() (which is bad). You have more decoupled code in the first one, which makes it easier to change and to test.
    – Aulis Ronkainen
    yesterday








  • 3




    Why would you do the first one? You're passing in a Setting and then ignoring its value.
    – Phil N DeBlanc
    yesterday






  • 1




    @PhilNDeBlanc it did not came from me. It came from here: medium.com/tech-tajawal/…
    – Daniel
    yesterday






  • 21




    I don't agree with the downvotes. While the subject matter may be considered trivial to experts, the question has merit: if dependency inversion should be used, then there should be a justification for using it.
    – Flater
    yesterday








  • 8




    @PhilNDeBlanc: This code is clearly oversimplified and not really indicative of real world logic. However, deactivateProfile suggests to me that setting the isActive to false without caring about its previous state is the correct approach here. Calling the method inherently means that you mean to set it as inactive, not get its current (in)active status.
    – Flater
    yesterday















up vote
51
down vote

favorite
16












I am having a hard time looking for resources on why should I use Dependency Injection. Most of the resources that I see explains that it just passes an instance of an object to another instance of an object but why? Is this just for cleaner architecture/code or does this affect performance as a whole?



Why should I do this:



class Profile {
public function deactivateProfile(Setting $setting)
{
$setting->isActive = false;
}
}


instead of this:



class Profile {
public function deactivateProfile()
{
$setting = new Setting();
$setting->isActive = false;
}
}








share


















  • 7




    You are introducing a hard-coded dependency to deactivateProfile() (which is bad). You have more decoupled code in the first one, which makes it easier to change and to test.
    – Aulis Ronkainen
    yesterday








  • 3




    Why would you do the first one? You're passing in a Setting and then ignoring its value.
    – Phil N DeBlanc
    yesterday






  • 1




    @PhilNDeBlanc it did not came from me. It came from here: medium.com/tech-tajawal/…
    – Daniel
    yesterday






  • 21




    I don't agree with the downvotes. While the subject matter may be considered trivial to experts, the question has merit: if dependency inversion should be used, then there should be a justification for using it.
    – Flater
    yesterday








  • 8




    @PhilNDeBlanc: This code is clearly oversimplified and not really indicative of real world logic. However, deactivateProfile suggests to me that setting the isActive to false without caring about its previous state is the correct approach here. Calling the method inherently means that you mean to set it as inactive, not get its current (in)active status.
    – Flater
    yesterday













up vote
51
down vote

favorite
16









up vote
51
down vote

favorite
16






16





I am having a hard time looking for resources on why should I use Dependency Injection. Most of the resources that I see explains that it just passes an instance of an object to another instance of an object but why? Is this just for cleaner architecture/code or does this affect performance as a whole?



Why should I do this:



class Profile {
public function deactivateProfile(Setting $setting)
{
$setting->isActive = false;
}
}


instead of this:



class Profile {
public function deactivateProfile()
{
$setting = new Setting();
$setting->isActive = false;
}
}








share













I am having a hard time looking for resources on why should I use Dependency Injection. Most of the resources that I see explains that it just passes an instance of an object to another instance of an object but why? Is this just for cleaner architecture/code or does this affect performance as a whole?



Why should I do this:



class Profile {
public function deactivateProfile(Setting $setting)
{
$setting->isActive = false;
}
}


instead of this:



class Profile {
public function deactivateProfile()
{
$setting = new Setting();
$setting->isActive = false;
}
}






architecture object-oriented-design clean-code





share












share










share



share










asked yesterday









Daniel

38924




38924








  • 7




    You are introducing a hard-coded dependency to deactivateProfile() (which is bad). You have more decoupled code in the first one, which makes it easier to change and to test.
    – Aulis Ronkainen
    yesterday








  • 3




    Why would you do the first one? You're passing in a Setting and then ignoring its value.
    – Phil N DeBlanc
    yesterday






  • 1




    @PhilNDeBlanc it did not came from me. It came from here: medium.com/tech-tajawal/…
    – Daniel
    yesterday






  • 21




    I don't agree with the downvotes. While the subject matter may be considered trivial to experts, the question has merit: if dependency inversion should be used, then there should be a justification for using it.
    – Flater
    yesterday








  • 8




    @PhilNDeBlanc: This code is clearly oversimplified and not really indicative of real world logic. However, deactivateProfile suggests to me that setting the isActive to false without caring about its previous state is the correct approach here. Calling the method inherently means that you mean to set it as inactive, not get its current (in)active status.
    – Flater
    yesterday














  • 7




    You are introducing a hard-coded dependency to deactivateProfile() (which is bad). You have more decoupled code in the first one, which makes it easier to change and to test.
    – Aulis Ronkainen
    yesterday








  • 3




    Why would you do the first one? You're passing in a Setting and then ignoring its value.
    – Phil N DeBlanc
    yesterday






  • 1




    @PhilNDeBlanc it did not came from me. It came from here: medium.com/tech-tajawal/…
    – Daniel
    yesterday






  • 21




    I don't agree with the downvotes. While the subject matter may be considered trivial to experts, the question has merit: if dependency inversion should be used, then there should be a justification for using it.
    – Flater
    yesterday








  • 8




    @PhilNDeBlanc: This code is clearly oversimplified and not really indicative of real world logic. However, deactivateProfile suggests to me that setting the isActive to false without caring about its previous state is the correct approach here. Calling the method inherently means that you mean to set it as inactive, not get its current (in)active status.
    – Flater
    yesterday








7




7




You are introducing a hard-coded dependency to deactivateProfile() (which is bad). You have more decoupled code in the first one, which makes it easier to change and to test.
– Aulis Ronkainen
yesterday






You are introducing a hard-coded dependency to deactivateProfile() (which is bad). You have more decoupled code in the first one, which makes it easier to change and to test.
– Aulis Ronkainen
yesterday






3




3




Why would you do the first one? You're passing in a Setting and then ignoring its value.
– Phil N DeBlanc
yesterday




Why would you do the first one? You're passing in a Setting and then ignoring its value.
– Phil N DeBlanc
yesterday




1




1




@PhilNDeBlanc it did not came from me. It came from here: medium.com/tech-tajawal/…
– Daniel
yesterday




@PhilNDeBlanc it did not came from me. It came from here: medium.com/tech-tajawal/…
– Daniel
yesterday




21




21




I don't agree with the downvotes. While the subject matter may be considered trivial to experts, the question has merit: if dependency inversion should be used, then there should be a justification for using it.
– Flater
yesterday






I don't agree with the downvotes. While the subject matter may be considered trivial to experts, the question has merit: if dependency inversion should be used, then there should be a justification for using it.
– Flater
yesterday






8




8




@PhilNDeBlanc: This code is clearly oversimplified and not really indicative of real world logic. However, deactivateProfile suggests to me that setting the isActive to false without caring about its previous state is the correct approach here. Calling the method inherently means that you mean to set it as inactive, not get its current (in)active status.
– Flater
yesterday




@PhilNDeBlanc: This code is clearly oversimplified and not really indicative of real world logic. However, deactivateProfile suggests to me that setting the isActive to false without caring about its previous state is the correct approach here. Calling the method inherently means that you mean to set it as inactive, not get its current (in)active status.
– Flater
yesterday










8 Answers
8






active

oldest

votes

















up vote
67
down vote













The advantage is that without dependency injection, your Profile class




  • needs to know how to create a Settings object (violates Single Responsibility Principle)

  • Always creates its Settings object the same way (creates a tight coupling between the two)


But with dependency injection




  • The logic for creating Settings objects is somewhere else

  • It's easy to use different kinds of Settings objects


This may seem (or even be) irrelevant in this particular case, but imagine if we're not talking about a Settings object, but a DataStore object, which might have different implementations, one that stores data in files and another that stores it in a database. And for automated tests you want a mock implementation as well. Now you really don't want the Profile class to hardcode which one it uses - and even more importantly, you really, really don't want the Profile class to know about filesystem paths, DB connections and passwords, so the creation of DataStore objects has to happen somewhere else.






share|improve this answer

















  • 12




    This may seem (or even be) irrelevant in this particular case I think it is very much relevant, in fact. How would you get the settings? A lot of systems I've seen will have a hard-coded default set of settings and a public facing configuration, so you'd need to load both and overwrite some values with the public settings. You may even need multiple sources of defaults. Perhaps you might even be getting some from disk, others from DB. So, the entire logic for even getting settings can, and often is, non-trivial - definitely not something consuming code should or would care about.
    – vlaz
    yesterday










  • We could also mention that object initialisation for a non-trivial component, such as a web service, would make $setting = new Setting(); horrendously inefficient. Injection and object instantiation happens once.
    – vikingsteve
    12 hours ago










  • @vikingsteve That's not important - you'd solve that problem more easily by using e.g. a singleton. And indeed, dependency injection doesn't mean you don't create the object multiple times. It just means that your class doesn't have control over the lifetime of its dependencies - you delegate it to something in your chain of callers.
    – Luaan
    5 hours ago






  • 2




    I think using mocks for testing should have more emphasis. Chances are if you look just at the code, it's always going to be a Settings object and will never change, so passing it in seems like a wasted effort. However, the very first time you try to test a Profile object by itself without also needing a Settings object (using a mock object instead as a solution) the need is very apparent.
    – JPhi1618
    4 hours ago










  • @Luaan "you'd solve that problem more easily by using e.g. a singleton" but that brings us to the first point in this answer: dependency injection avoids the tight coupling that would otherwise require the Profile class to know how to retrieve or create a settings object.
    – phoog
    4 hours ago


















up vote
38
down vote













Dependency Injection makes your code easier to test.



I learned this first-hand when I was tasked with fixing a hard-to-catch bug in Magento's PayPal integration.



An issue would arise when PayPal was telling Magento about a failed payment: Magento wouldn't register the failure properly.



Testing a potential fix "manually" would be very tedious: you'd need to somehow trigger a "Failed" PayPal notification. You'd have to submit an e-check, cancel it, and wait for it to error out. That means 3+ days to test a one-character code change!



Luckily, it appears that the Magento core devs who developed this function had testing in mind, and used a dependency injection pattern to make it trivial. This allows us to verify our work with a simple test case like this one:



<?php
// This is the dependency we will inject to facilitate our testing
class MockHttpClient extends Varien_Http_Adapter_Curl {
function read() {
// Make Magento think that PayPal said "VERIFIED", no matter what they actually said...
return "HTTP/1.1 200 OKnnVERIFIED";
}
}

// Here, we trick Magento into thinking PayPal actually sent something back.
// Magento will try to verify it against PayPal's API though, and since it's fake data, it'll always fail.
$ipnPayload = array (
'invoice' => '100058137', // Order ID to test against
'txn_id' => '04S87540L2309371A', // Test PayPal transaction ID
'payment_status' => 'Failed' // New payment status that Magento should ingest
);

// This is what Magento's controller calls during a normal IPN request.
// Instead of letting Magento talk to PayPal, we "inject" our fake HTTP client, which always returns VERIFIED.
Mage::getModel('paypal/ipn')->processIpnRequest($ipnPayload, new MockHttpClient());


I'm sure the DI pattern has plenty of other advantages, but increased testability is the single biggest benefit in my mind.



If you're curious about the solution to this problem, check out the GitHub repo here: https://github.com/bubbleupdev/BUCorefix_Paypalstatus






share|improve this answer

















  • 2




    Dependency injection makes code easier to test than code with hardcoded dependencies. Eliminating dependencies from business logic altogether is even better.
    – Ant P
    yesterday






  • 1




    And one major way to do what @AntP suggests is via parameterization. The logic to transform results coming back from the database into the object used to fill out a page template (commonly known as a "model") shouldn't even know a fetch is happening; it just needs to get those objects as input.
    – jpmc26
    22 hours ago








  • 3




    @jpmc26 indeed - I tend to harp on about functional core, imperative shell, which is really just a fancy name for passing data into your domain instead of injecting dependencies into it. The domain is pure, can be unit tested with no mocks and then is just wrapped in a shell that adapts things like persistence, messaging etc.
    – Ant P
    12 hours ago




















up vote
14
down vote













Why (what's even the issue)?




Why should I use dependency injection?




The best mnemonic I found for this is "new is glue": Every time you use new in your code, that code is tied down to that specific implementation. If you repeatedly use new in constructors, you will create a chain of specific implementations. And because you can't "have" an instance of a class without constructing it, you can't separate that chain.



As an example, imagine you're writing a race car video game. You started with a class Game, which creates a RaceTrack, which creates 8 Cars, which each create a Motor. Now if you want a second type of Car with a different acceleration, you will have to change every class mentioned, except maybe Game.



Cleaner code




Is this just for cleaner architecture/code




Yes.



However, it might very well seem less clear in this situation, because it's more an example of how to do it. The actual advantage only shows when several classes are involved and is more difficult to demonstrate, but imagine you would have used DI in the previous example. The code creating all those things might look something like this:



List<Car> cars = new List<Car>();
for(int i=0; i<8; i++){
float acceleration = 0.3f;
float maxSpeed = 200.0f;
Motor motor = new Motor(acceleration, maxSpeed);
Car car = new Car(motor);
cars.Add(car);
}
RaceTrack raceTrack = new RaceTrack(cars);
Game game = new Game(raceTrack);


Now you don't have to make any changes in RaceTrack, Game, Car, or Motor. That means two things:




  • the change is easier, because it's all in one place.

  • there's no way to introduce new bugs in classes you don't change!


Performance considerations




or does this affect performance as a whole?




No. But to be completely honest with you, it might.



However, even in that case, it's such a ridiculously small amount that you don't need to care. If at some point in the future, you have to write code for a tamagotchi with the equivalent of 5Mhz CPU and 2MB RAM, then maybe you might have to care about this.



In 99.999%* of cases it will have a better performance, because you spent less time fixing bugs and more time improving your resource-heavy algorithms.



*completely made up number



Added info: "hard-coded"



Make no mistake, this is still very much "hard-coded" - the numbers are written directly in the code. Not hard-coded would mean something like storing those values in a text file - e.g. in JSON format - and then reading them from that file.



In order to do that, you have to add code for reading a file and then parsing JSON. If you consider the example again; in the non-DI version, a Car or a Motor now has to read a file. That doesn't sound like it makes too much sense.



In the DI version, you would add it to the code setting up the game.






share|improve this answer



















  • 2




    Ad hard-coded, there is not really that much difference between code and config file. A file bundled with the application is a source even if you read dynamically. Pulling values from code to data files in json or whatever ‘config’ format helps nothing unless the values should be overridden by the user or depend on the environment.
    – Jan Hudec
    12 hours ago








  • 1




    I actually made a Tamagotchi once on an Arduino (16MHz, 2KB)
    – Jungkook
    11 hours ago










  • @JanHudec True. I actually had a longer explanation there, but decided to remove it to keep it shorter and focus on how it relates to DI. There's more stuff which isn't 100% correct; overall the answer is more optimized to push "the point" of DI without it getting too long. Or put differently, this is what I would have wanted to hear when I started out with DI.
    – R. Schmitz
    8 hours ago


















up vote
5
down vote













The example you give is not dependency injection in the classical sense. Dependency injection usually refers to passing objects in a constructor or by using "setter injection" just after the object is created, in order to set a value on a field in a newly created object.



Your example passes an object as an argument to an instance method. This instance method then modifies a field on that object. Dependency injection? No. Breaking encapsulation and data hiding? Absolutely!



Now, if the code was like this:



class Profile {
private $settings;

public function __construct(Settings $settings) {
$this->settings = $settings;
}

public function deactive() {
$this->settings->isActive = false;
}
}


Then I would say you are using dependency injection. The notable difference is a Settings object being passed in to the constructor or a Profile object.



This is useful if the Settings object is expensive or complex to construct, or Settings is an interface or abstract class where multiple concrete implementations exist in order to change run time behavior.



Since you are directly accessing a field on the Settings object rather than calling a method, you can't take advantage of Polymorphism, which is one of the benefits of dependency injection.



It looks like the Settings for a Profile are specific to that profile. In this case I would do one of the following:




  1. Instantiate the Settings object inside the Profile constructor


  2. Pass the Settings object in the constructor and copy over individual fields that apply to the Profile



Honestly, by passing the Settings object in to deactivateProfile and then modifying an internal field of the Settings object is a code smell. The Settings object should be the only one modifying its internal fields.






share|improve this answer

















  • 5




    The example you give is not dependency injection in the classical sense. -- It doesn't matter. OO people have objects on the brain, but you're still handing a dependency to something.
    – Robert Harvey
    yesterday










  • When you talk about “in the classical sense”, you are, as @RobertHarvey says, speaking purely in OO terms. In functional programming for example, injecting one function into another (higher order functions) is that paradigm’s classical example of dependency injection.
    – David Arno
    yesterday






  • 2




    @RobertHarvey: I guess I was taking too many liberties with "dependency injection." The place people most often think of the term and use the term is in reference to fields on an object being "injected" at the time of object construction, or immediately after in the case of setter injection.
    – Greg Burghardt
    yesterday










  • @DavidArno: Yes, you are correct. The OP seems to have an object oriented PHP code snippet in the question, so I was answering in that regard only, and not addressing functional programming --- all though with PHP you could ask the same question from the standpoint of functional programming.
    – Greg Burghardt
    yesterday


















up vote
2
down vote













I know I'm coming late to this party but I feel an important point is being missed.




Why should I do this:




class Profile {
public function deactivateProfile(Setting $setting)
{
$setting->isActive = false;
}
}


You shouldn't. But not because Dependency Injection is a bad idea. It's because this is doing it wrong.



Lets look at this things using code. We're going to do this:



$profile = new Profile();
$profile->deactivateProfile($setting);


when we get about the same thing out of this:



$setting->isActive = false; // Deactivate profile


So of course it seems like a waste of time. It is when you do it this way. This is not the best use of Dependency Injection. It's not even the best use of a class.



Now what if instead we had this:



$profile = new Profile($setting);

$application = new Application($profile);

$application.start();


And now the application is free to activate and deactivate the profile without having to know anything in particular about the setting that it's actually changing. Why is that good? In case you need to change setting. The application is walled off from those changes so you're free to go nuts in a safe contained space without having to watch everything break as soon as you touch something.



This follows the separate construction from behavior principle. The DI pattern here is a simple one. Build everything you need at as low a level as you can, wire them together, then start all the behavior ticking with one call.



The result is you have a separate place to decide what connects to what and a different place to manage what says what to whatever.



If that's not helpful to you then sure. DI, classes, object oriented programming, it's all a useless waste of time. Procedural code can solve all the same problems with less code.



Being able to make places in the code where I only have to think about a few things at the same time has really proved useful to me over the years. Sure it takes effort to make them. But once they're made I find working with them very relaxing. The people who maintain my code after I leave seem to like them too.



I know because I take the time to go back and visit my creations years later. You should to.






share|improve this answer























  • I was ready to upvote this until I got to the last three paragraphs, which come across as a bit patronising, or maybe just pessimistic. It's like you're assuming that the reader will ignore everything you've just said, and defensively responding to comments that haven't been made yet.
    – IMSoP
    3 hours ago


















up vote
0
down vote













You should use techniques to solve the problems they're good at solving when you have those problems. Dependency inversion and injection are no different.



Dependency inversion or injection is a technique that allows your code to decide on what implementation of a method gets called at run time. This maximizes the benefits of late binding. The technique is necessary when the language does not support run time replacement of non-instance functions. For example, Java lacks a mechanism to replace calls to a static method with calls to a different implementation; contrast with Python, where all that's necessary to replace the function call is to bind the name to a different function (reassign the variable holding the function).



Why would we want to vary the implementation of the function? There's a two main reasons:




  • We want to use fakes for testing purposes. This allows us to test a class that depends on a database fetch without actually connecting to the database.

  • We need to support multiple implementations. For example, we might need to set up a system that supports both MySQL and PostgreSQL databases.


You may also want to take note of inversion of control containers. This is a technique that is intended to help you avoid huge, tangled construction trees that look like this pseudocode:



thing5 =  new MyThing5();
thing3 = new MyThing3(thing5, new MyThing10());

myApp = new MyApp(
new MyAppDependency1(thing5, thing3),
new MyAppDependency2(
new Thing1(),
new Thing2(new Thing3(thing5, new Thing4(thing5)))
),
...
new MyAppDependency15(thing5)
);


It lets you register your classes and then does the construction for you:



injector.register(Thing1); // Yes, you'd need some kind of actual class reference.
injector.register(Thing2);
...
injector.register(MyAppDepdency15);
injector.register(MyApp);

myApp = injector.create(MyApp); // The injector fills in all the construction parameters.


Note that it's simplest if the classes registered can be stateless singletons.



Word of caution



Note that dependency inversion should not be your go-to answer for decoupling logic. Look for opportunities to use parameterization instead. Consider this pseudocode method for example:



myAverageAboveMin()
{
dbConn = new DbConnection("my connection string");
dbQuery = dbConn.makeQuery();
dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
dbQuery.setParam("min", 5);
dbQuery.Execute();
myData = dbQuery.getAll();
count = 0;
total = 0;
foreach (row in myData)
{
count++;
total += row.x;
}

return total / count;
}


We could use dependency inversion for some parts of this method:



class MyQuerier
{
private _dbConn;

MyQueries(dbConn) { this._dbConn = dbConn; }

fetchAboveMin(min)
{
dbQuery = this._dbConn.makeQuery();
dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
dbQuery.setParam("min", min);
dbQuery.Execute();
return dbQuery.getAll();
}
}


class Averager
{
private _querier;

Averager(querier) { this._querier = querier; }

myAverageAboveMin(min)
{
myData = this._querier.fetchAboveMin(min);
count = 0;
total = 0;
foreach (row in myData)
{
count++;
total += row.x;
}

return total / count;
}


But we shouldn't, at least not completely. Notice that we've created a stateful class with Querier. It now holds a reference to some essentially global connection object. This creates problems such as difficulty in understanding the overall state of the program and how different classes coordinate with each other. Notice also that we're forced to fake out the querier or the connection if we want to test the averaging logic. Further A better approach would be to increase parameterization:



class MyQuerier
{
fetchAboveMin(dbConn, min)
{
dbQuery = dbConn.makeQuery();
dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
dbQuery.setParam("min", min);
dbQuery.Execute();
return dbQuery.getAll();
}
}


class Averager
{
averageData(myData)
{
count = 0;
total = 0;
foreach (row in myData)
{
count++;
total += row.x;
}

return total / count;
}

class StuffDoer
{
private _querier;
private _averager;

StuffDoer(querier, averager)
{
this._querier = querier;
this._averager = averager;
}

myAverageAboveMin(dbConn, min)
{
myData = this._querier.fetchAboveMin(dbConn, min);
return this._averager.averageData(myData);
}
}


And the connection would be managed at some even higher level that's responsible for the operation as a whole and knows what to do with this output.



Now we can test the averaging logic completely independently of the querying, and what's more we can use it in a wider variety of situations. We might question whether we even need the MyQuerier and Averager objects, and maybe the answer is that we don't if we don't intend to unit test StuffDoer, and not unit testing StuffDoer would be perfectly reasonable since it's so tightly coupled to the database. It might make more sense to just let integration tests cover it. In that case, we might be fine making fetchAboveMin and averageData into static methods.






share|improve this answer



















  • 1




    "Dependency injection is a technique that is intended to help you avoid huge, tangled construction trees...". Your first example after this claim is an example of pure, or poor man's, dependency injection. The second is an example of using an IoC container to "automate" the injection of those dependencies. Both are examples of dependency injection in action.
    – David Arno
    yesterday










  • @DavidArno Yeah, you're right. I've adjusted the terminology.
    – jpmc26
    yesterday


















up vote
0
down vote













As a customer, when you hire a mechanic to do something to your car, do you expect that mechanic to build a car from scratch only to then work with it? No, you give the mechanic the car you want them to work on.



As the garage owner, when you instruct a mechanic to do something to a car, do you expect the mechanic to create his own screwdriver/wrench/car parts? No, you provide the mechanic with the parts/tools he needs to use



Why do we do this? Well, think about it. You're a garage owner who wants to hire someone to become your mechanic. You will teach them to be a mechanic (= you will write the code).



What's going to be easier:




  • Teach a mechanic how to attach a spoiler to a car using a screwdriver.

  • Teach a mechanic to create a car, create a spoiler, created a screwdriver
    and then attach the newly created spoiler to the newly created car with the newly created screwdriver.


There are massive benefits to not having your mechanic create everything from scratch:




  • Obviously, training (= development) is dramatically shortened if you just supply your mechanic with existing tools and parts.

  • If the same mechanic has to perform the same job multiple times, you can make sure he reuses the screwdriver instead of always throwing the old one out and creating a new one.

  • Additionally, a mechanic who has learned to create everything will need to be much more of an expert, and thus will expect a higher wage. The coding analogy here is that a class with many responsibilities is much harder to maintain than a class with a single strictly defined responsibility.

  • Additionally, when new inventions hit the market and spoilers are now being made from carbon instead of plastic; you will have to retrain (= redevelop) your expert mechanic. But your "simple" mechanic won't have to be retrained as long as the spoiler can still be attached in the same way.

  • Having a mechanic who doesn't rely on a car that they've built themselves means that you have a mechanic who is able to handle any car they may receive. Including cars that didn't even exist yet at the time of training the mechanic. However, your expert mechanic will not be able to build newer cars that have been created after their training.


If you hire and train the expert mechanic, you're going to end up with an employee who costs more, takes more time to perform what ought to be a simple job, and will perpetually need to be retrained whenever one of their many responsibilities need to be updated.



The development analogy is that if you use classes with hardcoded dependencies, then you're going to end up with hard to maintain classes which will need continual redevelopment/changes whenever a new version of the object (Settings in your case) is created, and you'll have to develop internal logic for the class to have the ability to create different types of Settings objects.



Furthermore, whoever consumes your class is now also going to have to ask the class to create the correct Settings object, as opposed to simply being able to pass the class any Settings object it wishes to pass. This means additional development for the consumer to figure out how to ask the class to create the right tool.





Yes, dependency inversion takes a bit more effort to write instead of hardcoding the dependency. Yes, it's annoying to have to type more.



But that is the same argument as choosing to hardcode literal values because "declaring variables takes more effort". Technically correct, but the pro's outweigh the cons by several orders of magnitude.



The benefit of dependency inversion is not experienced when you create the first version of the application. The benefit of dependency inversion is experienced when you need to change or extend that initial version. And don't trick yourself into thinking that you will get it right the first time and won't need to extend/change the code. You will have to change things.






does this affect performance as a whole?




This does not affect runtime performance of the application. But it massively impacts the development time (and therefore performance) of the developer.






share|improve this answer



















  • 2




    If you removed your comment, "As a minor comment, your question focuses on dependency inversion, not dependency injection. Injection is one way to do inversion, but it's not the only way.", this would be an excellent answer. Dependency inversion can be achieved via either injection or locator/globals. The question's examples relate to injection. So the question is about dependency injection (as well as dependency inversion).
    – David Arno
    yesterday










  • @DavidArno As I understand it, injection is the automated filling of method/constructor parameters as opposed to manually passing them. For the locator, does the locator itself then not become a dependency? It sounds like it's shifting the problem.
    – Flater
    yesterday






  • 11




    I think the whole car thing is a bit belaboured and confusing
    – Ewan
    yesterday






  • 3




    @Flater, part of the problem is no one really seems to agree on what the difference between dependency injection, dependency inversion and inversion of control are. One thing is for certain though, a "container" most certainly isn't needed to inject a dependency into a method or constructor. Pure (or poor man's) DI specifically describes manual dependency injection. It's the only dependency injection I personally use as I dislike the "magic" associated with containers.
    – David Arno
    yesterday






  • 1




    Your mechanic analogy is poor even as an analogy. If I have a mechanic trained how to fix cars, he can fix most varieties but if I come to him with a EV instead, he's likely to have no clue what to do with it. DI does not fix the polymorphic problem, all it does is help with coupling - ie how to get the car and mechanic together. A better analogy is a mechanic working for a dealer who only fixed 1 brand of car going independent and fixing other brands of car.
    – gbjbaanb
    5 hours ago


















up vote
0
down vote













I was always baffled by dependency injection. It seemed to only exist within Java spheres, but those spheres spoke of it with great reverence. It was one of the great Patterns, you see, which are said to bring order to chaos. But the examples were always convoluted and artificial, establishing a non-problem and then setting out to solve it by making the code more complicated.



It made more sense when a fellow Python dev imparted to me this wisdom: it's just passing arguments to functions. It's barely a pattern at all; more like a reminder that you can ask for something as an argument, even if you could have conceivably provided a reasonable value yourself.



So your question is roughly equivalent to "why should my function take arguments?" and has many of the same answers, namely: to let the caller make decisions.



This comes with a cost, of course, because now you're forcing the caller to make some decision (unless you make the argument optional), and the interface is somewhat more complex. In exchange, you gain flexibility.



So: Is there a good reason you specifically need to use this particular Setting type/value? Is there a good reason calling code might want a different Setting type/value? (Remember, tests are code!)






share|improve this answer








New contributor




Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

















    protected by gnat 33 mins ago



    Thank you for your interest in this question.
    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



    Would you like to answer one of these unanswered questions instead?














    8 Answers
    8






    active

    oldest

    votes








    8 Answers
    8






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    67
    down vote













    The advantage is that without dependency injection, your Profile class




    • needs to know how to create a Settings object (violates Single Responsibility Principle)

    • Always creates its Settings object the same way (creates a tight coupling between the two)


    But with dependency injection




    • The logic for creating Settings objects is somewhere else

    • It's easy to use different kinds of Settings objects


    This may seem (or even be) irrelevant in this particular case, but imagine if we're not talking about a Settings object, but a DataStore object, which might have different implementations, one that stores data in files and another that stores it in a database. And for automated tests you want a mock implementation as well. Now you really don't want the Profile class to hardcode which one it uses - and even more importantly, you really, really don't want the Profile class to know about filesystem paths, DB connections and passwords, so the creation of DataStore objects has to happen somewhere else.






    share|improve this answer

















    • 12




      This may seem (or even be) irrelevant in this particular case I think it is very much relevant, in fact. How would you get the settings? A lot of systems I've seen will have a hard-coded default set of settings and a public facing configuration, so you'd need to load both and overwrite some values with the public settings. You may even need multiple sources of defaults. Perhaps you might even be getting some from disk, others from DB. So, the entire logic for even getting settings can, and often is, non-trivial - definitely not something consuming code should or would care about.
      – vlaz
      yesterday










    • We could also mention that object initialisation for a non-trivial component, such as a web service, would make $setting = new Setting(); horrendously inefficient. Injection and object instantiation happens once.
      – vikingsteve
      12 hours ago










    • @vikingsteve That's not important - you'd solve that problem more easily by using e.g. a singleton. And indeed, dependency injection doesn't mean you don't create the object multiple times. It just means that your class doesn't have control over the lifetime of its dependencies - you delegate it to something in your chain of callers.
      – Luaan
      5 hours ago






    • 2




      I think using mocks for testing should have more emphasis. Chances are if you look just at the code, it's always going to be a Settings object and will never change, so passing it in seems like a wasted effort. However, the very first time you try to test a Profile object by itself without also needing a Settings object (using a mock object instead as a solution) the need is very apparent.
      – JPhi1618
      4 hours ago










    • @Luaan "you'd solve that problem more easily by using e.g. a singleton" but that brings us to the first point in this answer: dependency injection avoids the tight coupling that would otherwise require the Profile class to know how to retrieve or create a settings object.
      – phoog
      4 hours ago















    up vote
    67
    down vote













    The advantage is that without dependency injection, your Profile class




    • needs to know how to create a Settings object (violates Single Responsibility Principle)

    • Always creates its Settings object the same way (creates a tight coupling between the two)


    But with dependency injection




    • The logic for creating Settings objects is somewhere else

    • It's easy to use different kinds of Settings objects


    This may seem (or even be) irrelevant in this particular case, but imagine if we're not talking about a Settings object, but a DataStore object, which might have different implementations, one that stores data in files and another that stores it in a database. And for automated tests you want a mock implementation as well. Now you really don't want the Profile class to hardcode which one it uses - and even more importantly, you really, really don't want the Profile class to know about filesystem paths, DB connections and passwords, so the creation of DataStore objects has to happen somewhere else.






    share|improve this answer

















    • 12




      This may seem (or even be) irrelevant in this particular case I think it is very much relevant, in fact. How would you get the settings? A lot of systems I've seen will have a hard-coded default set of settings and a public facing configuration, so you'd need to load both and overwrite some values with the public settings. You may even need multiple sources of defaults. Perhaps you might even be getting some from disk, others from DB. So, the entire logic for even getting settings can, and often is, non-trivial - definitely not something consuming code should or would care about.
      – vlaz
      yesterday










    • We could also mention that object initialisation for a non-trivial component, such as a web service, would make $setting = new Setting(); horrendously inefficient. Injection and object instantiation happens once.
      – vikingsteve
      12 hours ago










    • @vikingsteve That's not important - you'd solve that problem more easily by using e.g. a singleton. And indeed, dependency injection doesn't mean you don't create the object multiple times. It just means that your class doesn't have control over the lifetime of its dependencies - you delegate it to something in your chain of callers.
      – Luaan
      5 hours ago






    • 2




      I think using mocks for testing should have more emphasis. Chances are if you look just at the code, it's always going to be a Settings object and will never change, so passing it in seems like a wasted effort. However, the very first time you try to test a Profile object by itself without also needing a Settings object (using a mock object instead as a solution) the need is very apparent.
      – JPhi1618
      4 hours ago










    • @Luaan "you'd solve that problem more easily by using e.g. a singleton" but that brings us to the first point in this answer: dependency injection avoids the tight coupling that would otherwise require the Profile class to know how to retrieve or create a settings object.
      – phoog
      4 hours ago













    up vote
    67
    down vote










    up vote
    67
    down vote









    The advantage is that without dependency injection, your Profile class




    • needs to know how to create a Settings object (violates Single Responsibility Principle)

    • Always creates its Settings object the same way (creates a tight coupling between the two)


    But with dependency injection




    • The logic for creating Settings objects is somewhere else

    • It's easy to use different kinds of Settings objects


    This may seem (or even be) irrelevant in this particular case, but imagine if we're not talking about a Settings object, but a DataStore object, which might have different implementations, one that stores data in files and another that stores it in a database. And for automated tests you want a mock implementation as well. Now you really don't want the Profile class to hardcode which one it uses - and even more importantly, you really, really don't want the Profile class to know about filesystem paths, DB connections and passwords, so the creation of DataStore objects has to happen somewhere else.






    share|improve this answer












    The advantage is that without dependency injection, your Profile class




    • needs to know how to create a Settings object (violates Single Responsibility Principle)

    • Always creates its Settings object the same way (creates a tight coupling between the two)


    But with dependency injection




    • The logic for creating Settings objects is somewhere else

    • It's easy to use different kinds of Settings objects


    This may seem (or even be) irrelevant in this particular case, but imagine if we're not talking about a Settings object, but a DataStore object, which might have different implementations, one that stores data in files and another that stores it in a database. And for automated tests you want a mock implementation as well. Now you really don't want the Profile class to hardcode which one it uses - and even more importantly, you really, really don't want the Profile class to know about filesystem paths, DB connections and passwords, so the creation of DataStore objects has to happen somewhere else.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered yesterday









    Michael Borgwardt

    42.7k1097156




    42.7k1097156








    • 12




      This may seem (or even be) irrelevant in this particular case I think it is very much relevant, in fact. How would you get the settings? A lot of systems I've seen will have a hard-coded default set of settings and a public facing configuration, so you'd need to load both and overwrite some values with the public settings. You may even need multiple sources of defaults. Perhaps you might even be getting some from disk, others from DB. So, the entire logic for even getting settings can, and often is, non-trivial - definitely not something consuming code should or would care about.
      – vlaz
      yesterday










    • We could also mention that object initialisation for a non-trivial component, such as a web service, would make $setting = new Setting(); horrendously inefficient. Injection and object instantiation happens once.
      – vikingsteve
      12 hours ago










    • @vikingsteve That's not important - you'd solve that problem more easily by using e.g. a singleton. And indeed, dependency injection doesn't mean you don't create the object multiple times. It just means that your class doesn't have control over the lifetime of its dependencies - you delegate it to something in your chain of callers.
      – Luaan
      5 hours ago






    • 2




      I think using mocks for testing should have more emphasis. Chances are if you look just at the code, it's always going to be a Settings object and will never change, so passing it in seems like a wasted effort. However, the very first time you try to test a Profile object by itself without also needing a Settings object (using a mock object instead as a solution) the need is very apparent.
      – JPhi1618
      4 hours ago










    • @Luaan "you'd solve that problem more easily by using e.g. a singleton" but that brings us to the first point in this answer: dependency injection avoids the tight coupling that would otherwise require the Profile class to know how to retrieve or create a settings object.
      – phoog
      4 hours ago














    • 12




      This may seem (or even be) irrelevant in this particular case I think it is very much relevant, in fact. How would you get the settings? A lot of systems I've seen will have a hard-coded default set of settings and a public facing configuration, so you'd need to load both and overwrite some values with the public settings. You may even need multiple sources of defaults. Perhaps you might even be getting some from disk, others from DB. So, the entire logic for even getting settings can, and often is, non-trivial - definitely not something consuming code should or would care about.
      – vlaz
      yesterday










    • We could also mention that object initialisation for a non-trivial component, such as a web service, would make $setting = new Setting(); horrendously inefficient. Injection and object instantiation happens once.
      – vikingsteve
      12 hours ago










    • @vikingsteve That's not important - you'd solve that problem more easily by using e.g. a singleton. And indeed, dependency injection doesn't mean you don't create the object multiple times. It just means that your class doesn't have control over the lifetime of its dependencies - you delegate it to something in your chain of callers.
      – Luaan
      5 hours ago






    • 2




      I think using mocks for testing should have more emphasis. Chances are if you look just at the code, it's always going to be a Settings object and will never change, so passing it in seems like a wasted effort. However, the very first time you try to test a Profile object by itself without also needing a Settings object (using a mock object instead as a solution) the need is very apparent.
      – JPhi1618
      4 hours ago










    • @Luaan "you'd solve that problem more easily by using e.g. a singleton" but that brings us to the first point in this answer: dependency injection avoids the tight coupling that would otherwise require the Profile class to know how to retrieve or create a settings object.
      – phoog
      4 hours ago








    12




    12




    This may seem (or even be) irrelevant in this particular case I think it is very much relevant, in fact. How would you get the settings? A lot of systems I've seen will have a hard-coded default set of settings and a public facing configuration, so you'd need to load both and overwrite some values with the public settings. You may even need multiple sources of defaults. Perhaps you might even be getting some from disk, others from DB. So, the entire logic for even getting settings can, and often is, non-trivial - definitely not something consuming code should or would care about.
    – vlaz
    yesterday




    This may seem (or even be) irrelevant in this particular case I think it is very much relevant, in fact. How would you get the settings? A lot of systems I've seen will have a hard-coded default set of settings and a public facing configuration, so you'd need to load both and overwrite some values with the public settings. You may even need multiple sources of defaults. Perhaps you might even be getting some from disk, others from DB. So, the entire logic for even getting settings can, and often is, non-trivial - definitely not something consuming code should or would care about.
    – vlaz
    yesterday












    We could also mention that object initialisation for a non-trivial component, such as a web service, would make $setting = new Setting(); horrendously inefficient. Injection and object instantiation happens once.
    – vikingsteve
    12 hours ago




    We could also mention that object initialisation for a non-trivial component, such as a web service, would make $setting = new Setting(); horrendously inefficient. Injection and object instantiation happens once.
    – vikingsteve
    12 hours ago












    @vikingsteve That's not important - you'd solve that problem more easily by using e.g. a singleton. And indeed, dependency injection doesn't mean you don't create the object multiple times. It just means that your class doesn't have control over the lifetime of its dependencies - you delegate it to something in your chain of callers.
    – Luaan
    5 hours ago




    @vikingsteve That's not important - you'd solve that problem more easily by using e.g. a singleton. And indeed, dependency injection doesn't mean you don't create the object multiple times. It just means that your class doesn't have control over the lifetime of its dependencies - you delegate it to something in your chain of callers.
    – Luaan
    5 hours ago




    2




    2




    I think using mocks for testing should have more emphasis. Chances are if you look just at the code, it's always going to be a Settings object and will never change, so passing it in seems like a wasted effort. However, the very first time you try to test a Profile object by itself without also needing a Settings object (using a mock object instead as a solution) the need is very apparent.
    – JPhi1618
    4 hours ago




    I think using mocks for testing should have more emphasis. Chances are if you look just at the code, it's always going to be a Settings object and will never change, so passing it in seems like a wasted effort. However, the very first time you try to test a Profile object by itself without also needing a Settings object (using a mock object instead as a solution) the need is very apparent.
    – JPhi1618
    4 hours ago












    @Luaan "you'd solve that problem more easily by using e.g. a singleton" but that brings us to the first point in this answer: dependency injection avoids the tight coupling that would otherwise require the Profile class to know how to retrieve or create a settings object.
    – phoog
    4 hours ago




    @Luaan "you'd solve that problem more easily by using e.g. a singleton" but that brings us to the first point in this answer: dependency injection avoids the tight coupling that would otherwise require the Profile class to know how to retrieve or create a settings object.
    – phoog
    4 hours ago












    up vote
    38
    down vote













    Dependency Injection makes your code easier to test.



    I learned this first-hand when I was tasked with fixing a hard-to-catch bug in Magento's PayPal integration.



    An issue would arise when PayPal was telling Magento about a failed payment: Magento wouldn't register the failure properly.



    Testing a potential fix "manually" would be very tedious: you'd need to somehow trigger a "Failed" PayPal notification. You'd have to submit an e-check, cancel it, and wait for it to error out. That means 3+ days to test a one-character code change!



    Luckily, it appears that the Magento core devs who developed this function had testing in mind, and used a dependency injection pattern to make it trivial. This allows us to verify our work with a simple test case like this one:



    <?php
    // This is the dependency we will inject to facilitate our testing
    class MockHttpClient extends Varien_Http_Adapter_Curl {
    function read() {
    // Make Magento think that PayPal said "VERIFIED", no matter what they actually said...
    return "HTTP/1.1 200 OKnnVERIFIED";
    }
    }

    // Here, we trick Magento into thinking PayPal actually sent something back.
    // Magento will try to verify it against PayPal's API though, and since it's fake data, it'll always fail.
    $ipnPayload = array (
    'invoice' => '100058137', // Order ID to test against
    'txn_id' => '04S87540L2309371A', // Test PayPal transaction ID
    'payment_status' => 'Failed' // New payment status that Magento should ingest
    );

    // This is what Magento's controller calls during a normal IPN request.
    // Instead of letting Magento talk to PayPal, we "inject" our fake HTTP client, which always returns VERIFIED.
    Mage::getModel('paypal/ipn')->processIpnRequest($ipnPayload, new MockHttpClient());


    I'm sure the DI pattern has plenty of other advantages, but increased testability is the single biggest benefit in my mind.



    If you're curious about the solution to this problem, check out the GitHub repo here: https://github.com/bubbleupdev/BUCorefix_Paypalstatus






    share|improve this answer

















    • 2




      Dependency injection makes code easier to test than code with hardcoded dependencies. Eliminating dependencies from business logic altogether is even better.
      – Ant P
      yesterday






    • 1




      And one major way to do what @AntP suggests is via parameterization. The logic to transform results coming back from the database into the object used to fill out a page template (commonly known as a "model") shouldn't even know a fetch is happening; it just needs to get those objects as input.
      – jpmc26
      22 hours ago








    • 3




      @jpmc26 indeed - I tend to harp on about functional core, imperative shell, which is really just a fancy name for passing data into your domain instead of injecting dependencies into it. The domain is pure, can be unit tested with no mocks and then is just wrapped in a shell that adapts things like persistence, messaging etc.
      – Ant P
      12 hours ago

















    up vote
    38
    down vote













    Dependency Injection makes your code easier to test.



    I learned this first-hand when I was tasked with fixing a hard-to-catch bug in Magento's PayPal integration.



    An issue would arise when PayPal was telling Magento about a failed payment: Magento wouldn't register the failure properly.



    Testing a potential fix "manually" would be very tedious: you'd need to somehow trigger a "Failed" PayPal notification. You'd have to submit an e-check, cancel it, and wait for it to error out. That means 3+ days to test a one-character code change!



    Luckily, it appears that the Magento core devs who developed this function had testing in mind, and used a dependency injection pattern to make it trivial. This allows us to verify our work with a simple test case like this one:



    <?php
    // This is the dependency we will inject to facilitate our testing
    class MockHttpClient extends Varien_Http_Adapter_Curl {
    function read() {
    // Make Magento think that PayPal said "VERIFIED", no matter what they actually said...
    return "HTTP/1.1 200 OKnnVERIFIED";
    }
    }

    // Here, we trick Magento into thinking PayPal actually sent something back.
    // Magento will try to verify it against PayPal's API though, and since it's fake data, it'll always fail.
    $ipnPayload = array (
    'invoice' => '100058137', // Order ID to test against
    'txn_id' => '04S87540L2309371A', // Test PayPal transaction ID
    'payment_status' => 'Failed' // New payment status that Magento should ingest
    );

    // This is what Magento's controller calls during a normal IPN request.
    // Instead of letting Magento talk to PayPal, we "inject" our fake HTTP client, which always returns VERIFIED.
    Mage::getModel('paypal/ipn')->processIpnRequest($ipnPayload, new MockHttpClient());


    I'm sure the DI pattern has plenty of other advantages, but increased testability is the single biggest benefit in my mind.



    If you're curious about the solution to this problem, check out the GitHub repo here: https://github.com/bubbleupdev/BUCorefix_Paypalstatus






    share|improve this answer

















    • 2




      Dependency injection makes code easier to test than code with hardcoded dependencies. Eliminating dependencies from business logic altogether is even better.
      – Ant P
      yesterday






    • 1




      And one major way to do what @AntP suggests is via parameterization. The logic to transform results coming back from the database into the object used to fill out a page template (commonly known as a "model") shouldn't even know a fetch is happening; it just needs to get those objects as input.
      – jpmc26
      22 hours ago








    • 3




      @jpmc26 indeed - I tend to harp on about functional core, imperative shell, which is really just a fancy name for passing data into your domain instead of injecting dependencies into it. The domain is pure, can be unit tested with no mocks and then is just wrapped in a shell that adapts things like persistence, messaging etc.
      – Ant P
      12 hours ago















    up vote
    38
    down vote










    up vote
    38
    down vote









    Dependency Injection makes your code easier to test.



    I learned this first-hand when I was tasked with fixing a hard-to-catch bug in Magento's PayPal integration.



    An issue would arise when PayPal was telling Magento about a failed payment: Magento wouldn't register the failure properly.



    Testing a potential fix "manually" would be very tedious: you'd need to somehow trigger a "Failed" PayPal notification. You'd have to submit an e-check, cancel it, and wait for it to error out. That means 3+ days to test a one-character code change!



    Luckily, it appears that the Magento core devs who developed this function had testing in mind, and used a dependency injection pattern to make it trivial. This allows us to verify our work with a simple test case like this one:



    <?php
    // This is the dependency we will inject to facilitate our testing
    class MockHttpClient extends Varien_Http_Adapter_Curl {
    function read() {
    // Make Magento think that PayPal said "VERIFIED", no matter what they actually said...
    return "HTTP/1.1 200 OKnnVERIFIED";
    }
    }

    // Here, we trick Magento into thinking PayPal actually sent something back.
    // Magento will try to verify it against PayPal's API though, and since it's fake data, it'll always fail.
    $ipnPayload = array (
    'invoice' => '100058137', // Order ID to test against
    'txn_id' => '04S87540L2309371A', // Test PayPal transaction ID
    'payment_status' => 'Failed' // New payment status that Magento should ingest
    );

    // This is what Magento's controller calls during a normal IPN request.
    // Instead of letting Magento talk to PayPal, we "inject" our fake HTTP client, which always returns VERIFIED.
    Mage::getModel('paypal/ipn')->processIpnRequest($ipnPayload, new MockHttpClient());


    I'm sure the DI pattern has plenty of other advantages, but increased testability is the single biggest benefit in my mind.



    If you're curious about the solution to this problem, check out the GitHub repo here: https://github.com/bubbleupdev/BUCorefix_Paypalstatus






    share|improve this answer












    Dependency Injection makes your code easier to test.



    I learned this first-hand when I was tasked with fixing a hard-to-catch bug in Magento's PayPal integration.



    An issue would arise when PayPal was telling Magento about a failed payment: Magento wouldn't register the failure properly.



    Testing a potential fix "manually" would be very tedious: you'd need to somehow trigger a "Failed" PayPal notification. You'd have to submit an e-check, cancel it, and wait for it to error out. That means 3+ days to test a one-character code change!



    Luckily, it appears that the Magento core devs who developed this function had testing in mind, and used a dependency injection pattern to make it trivial. This allows us to verify our work with a simple test case like this one:



    <?php
    // This is the dependency we will inject to facilitate our testing
    class MockHttpClient extends Varien_Http_Adapter_Curl {
    function read() {
    // Make Magento think that PayPal said "VERIFIED", no matter what they actually said...
    return "HTTP/1.1 200 OKnnVERIFIED";
    }
    }

    // Here, we trick Magento into thinking PayPal actually sent something back.
    // Magento will try to verify it against PayPal's API though, and since it's fake data, it'll always fail.
    $ipnPayload = array (
    'invoice' => '100058137', // Order ID to test against
    'txn_id' => '04S87540L2309371A', // Test PayPal transaction ID
    'payment_status' => 'Failed' // New payment status that Magento should ingest
    );

    // This is what Magento's controller calls during a normal IPN request.
    // Instead of letting Magento talk to PayPal, we "inject" our fake HTTP client, which always returns VERIFIED.
    Mage::getModel('paypal/ipn')->processIpnRequest($ipnPayload, new MockHttpClient());


    I'm sure the DI pattern has plenty of other advantages, but increased testability is the single biggest benefit in my mind.



    If you're curious about the solution to this problem, check out the GitHub repo here: https://github.com/bubbleupdev/BUCorefix_Paypalstatus







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered yesterday









    Eric Seastrand

    45238




    45238








    • 2




      Dependency injection makes code easier to test than code with hardcoded dependencies. Eliminating dependencies from business logic altogether is even better.
      – Ant P
      yesterday






    • 1




      And one major way to do what @AntP suggests is via parameterization. The logic to transform results coming back from the database into the object used to fill out a page template (commonly known as a "model") shouldn't even know a fetch is happening; it just needs to get those objects as input.
      – jpmc26
      22 hours ago








    • 3




      @jpmc26 indeed - I tend to harp on about functional core, imperative shell, which is really just a fancy name for passing data into your domain instead of injecting dependencies into it. The domain is pure, can be unit tested with no mocks and then is just wrapped in a shell that adapts things like persistence, messaging etc.
      – Ant P
      12 hours ago
















    • 2




      Dependency injection makes code easier to test than code with hardcoded dependencies. Eliminating dependencies from business logic altogether is even better.
      – Ant P
      yesterday






    • 1




      And one major way to do what @AntP suggests is via parameterization. The logic to transform results coming back from the database into the object used to fill out a page template (commonly known as a "model") shouldn't even know a fetch is happening; it just needs to get those objects as input.
      – jpmc26
      22 hours ago








    • 3




      @jpmc26 indeed - I tend to harp on about functional core, imperative shell, which is really just a fancy name for passing data into your domain instead of injecting dependencies into it. The domain is pure, can be unit tested with no mocks and then is just wrapped in a shell that adapts things like persistence, messaging etc.
      – Ant P
      12 hours ago










    2




    2




    Dependency injection makes code easier to test than code with hardcoded dependencies. Eliminating dependencies from business logic altogether is even better.
    – Ant P
    yesterday




    Dependency injection makes code easier to test than code with hardcoded dependencies. Eliminating dependencies from business logic altogether is even better.
    – Ant P
    yesterday




    1




    1




    And one major way to do what @AntP suggests is via parameterization. The logic to transform results coming back from the database into the object used to fill out a page template (commonly known as a "model") shouldn't even know a fetch is happening; it just needs to get those objects as input.
    – jpmc26
    22 hours ago






    And one major way to do what @AntP suggests is via parameterization. The logic to transform results coming back from the database into the object used to fill out a page template (commonly known as a "model") shouldn't even know a fetch is happening; it just needs to get those objects as input.
    – jpmc26
    22 hours ago






    3




    3




    @jpmc26 indeed - I tend to harp on about functional core, imperative shell, which is really just a fancy name for passing data into your domain instead of injecting dependencies into it. The domain is pure, can be unit tested with no mocks and then is just wrapped in a shell that adapts things like persistence, messaging etc.
    – Ant P
    12 hours ago






    @jpmc26 indeed - I tend to harp on about functional core, imperative shell, which is really just a fancy name for passing data into your domain instead of injecting dependencies into it. The domain is pure, can be unit tested with no mocks and then is just wrapped in a shell that adapts things like persistence, messaging etc.
    – Ant P
    12 hours ago












    up vote
    14
    down vote













    Why (what's even the issue)?




    Why should I use dependency injection?




    The best mnemonic I found for this is "new is glue": Every time you use new in your code, that code is tied down to that specific implementation. If you repeatedly use new in constructors, you will create a chain of specific implementations. And because you can't "have" an instance of a class without constructing it, you can't separate that chain.



    As an example, imagine you're writing a race car video game. You started with a class Game, which creates a RaceTrack, which creates 8 Cars, which each create a Motor. Now if you want a second type of Car with a different acceleration, you will have to change every class mentioned, except maybe Game.



    Cleaner code




    Is this just for cleaner architecture/code




    Yes.



    However, it might very well seem less clear in this situation, because it's more an example of how to do it. The actual advantage only shows when several classes are involved and is more difficult to demonstrate, but imagine you would have used DI in the previous example. The code creating all those things might look something like this:



    List<Car> cars = new List<Car>();
    for(int i=0; i<8; i++){
    float acceleration = 0.3f;
    float maxSpeed = 200.0f;
    Motor motor = new Motor(acceleration, maxSpeed);
    Car car = new Car(motor);
    cars.Add(car);
    }
    RaceTrack raceTrack = new RaceTrack(cars);
    Game game = new Game(raceTrack);


    Now you don't have to make any changes in RaceTrack, Game, Car, or Motor. That means two things:




    • the change is easier, because it's all in one place.

    • there's no way to introduce new bugs in classes you don't change!


    Performance considerations




    or does this affect performance as a whole?




    No. But to be completely honest with you, it might.



    However, even in that case, it's such a ridiculously small amount that you don't need to care. If at some point in the future, you have to write code for a tamagotchi with the equivalent of 5Mhz CPU and 2MB RAM, then maybe you might have to care about this.



    In 99.999%* of cases it will have a better performance, because you spent less time fixing bugs and more time improving your resource-heavy algorithms.



    *completely made up number



    Added info: "hard-coded"



    Make no mistake, this is still very much "hard-coded" - the numbers are written directly in the code. Not hard-coded would mean something like storing those values in a text file - e.g. in JSON format - and then reading them from that file.



    In order to do that, you have to add code for reading a file and then parsing JSON. If you consider the example again; in the non-DI version, a Car or a Motor now has to read a file. That doesn't sound like it makes too much sense.



    In the DI version, you would add it to the code setting up the game.






    share|improve this answer



















    • 2




      Ad hard-coded, there is not really that much difference between code and config file. A file bundled with the application is a source even if you read dynamically. Pulling values from code to data files in json or whatever ‘config’ format helps nothing unless the values should be overridden by the user or depend on the environment.
      – Jan Hudec
      12 hours ago








    • 1




      I actually made a Tamagotchi once on an Arduino (16MHz, 2KB)
      – Jungkook
      11 hours ago










    • @JanHudec True. I actually had a longer explanation there, but decided to remove it to keep it shorter and focus on how it relates to DI. There's more stuff which isn't 100% correct; overall the answer is more optimized to push "the point" of DI without it getting too long. Or put differently, this is what I would have wanted to hear when I started out with DI.
      – R. Schmitz
      8 hours ago















    up vote
    14
    down vote













    Why (what's even the issue)?




    Why should I use dependency injection?




    The best mnemonic I found for this is "new is glue": Every time you use new in your code, that code is tied down to that specific implementation. If you repeatedly use new in constructors, you will create a chain of specific implementations. And because you can't "have" an instance of a class without constructing it, you can't separate that chain.



    As an example, imagine you're writing a race car video game. You started with a class Game, which creates a RaceTrack, which creates 8 Cars, which each create a Motor. Now if you want a second type of Car with a different acceleration, you will have to change every class mentioned, except maybe Game.



    Cleaner code




    Is this just for cleaner architecture/code




    Yes.



    However, it might very well seem less clear in this situation, because it's more an example of how to do it. The actual advantage only shows when several classes are involved and is more difficult to demonstrate, but imagine you would have used DI in the previous example. The code creating all those things might look something like this:



    List<Car> cars = new List<Car>();
    for(int i=0; i<8; i++){
    float acceleration = 0.3f;
    float maxSpeed = 200.0f;
    Motor motor = new Motor(acceleration, maxSpeed);
    Car car = new Car(motor);
    cars.Add(car);
    }
    RaceTrack raceTrack = new RaceTrack(cars);
    Game game = new Game(raceTrack);


    Now you don't have to make any changes in RaceTrack, Game, Car, or Motor. That means two things:




    • the change is easier, because it's all in one place.

    • there's no way to introduce new bugs in classes you don't change!


    Performance considerations




    or does this affect performance as a whole?




    No. But to be completely honest with you, it might.



    However, even in that case, it's such a ridiculously small amount that you don't need to care. If at some point in the future, you have to write code for a tamagotchi with the equivalent of 5Mhz CPU and 2MB RAM, then maybe you might have to care about this.



    In 99.999%* of cases it will have a better performance, because you spent less time fixing bugs and more time improving your resource-heavy algorithms.



    *completely made up number



    Added info: "hard-coded"



    Make no mistake, this is still very much "hard-coded" - the numbers are written directly in the code. Not hard-coded would mean something like storing those values in a text file - e.g. in JSON format - and then reading them from that file.



    In order to do that, you have to add code for reading a file and then parsing JSON. If you consider the example again; in the non-DI version, a Car or a Motor now has to read a file. That doesn't sound like it makes too much sense.



    In the DI version, you would add it to the code setting up the game.






    share|improve this answer



















    • 2




      Ad hard-coded, there is not really that much difference between code and config file. A file bundled with the application is a source even if you read dynamically. Pulling values from code to data files in json or whatever ‘config’ format helps nothing unless the values should be overridden by the user or depend on the environment.
      – Jan Hudec
      12 hours ago








    • 1




      I actually made a Tamagotchi once on an Arduino (16MHz, 2KB)
      – Jungkook
      11 hours ago










    • @JanHudec True. I actually had a longer explanation there, but decided to remove it to keep it shorter and focus on how it relates to DI. There's more stuff which isn't 100% correct; overall the answer is more optimized to push "the point" of DI without it getting too long. Or put differently, this is what I would have wanted to hear when I started out with DI.
      – R. Schmitz
      8 hours ago













    up vote
    14
    down vote










    up vote
    14
    down vote









    Why (what's even the issue)?




    Why should I use dependency injection?




    The best mnemonic I found for this is "new is glue": Every time you use new in your code, that code is tied down to that specific implementation. If you repeatedly use new in constructors, you will create a chain of specific implementations. And because you can't "have" an instance of a class without constructing it, you can't separate that chain.



    As an example, imagine you're writing a race car video game. You started with a class Game, which creates a RaceTrack, which creates 8 Cars, which each create a Motor. Now if you want a second type of Car with a different acceleration, you will have to change every class mentioned, except maybe Game.



    Cleaner code




    Is this just for cleaner architecture/code




    Yes.



    However, it might very well seem less clear in this situation, because it's more an example of how to do it. The actual advantage only shows when several classes are involved and is more difficult to demonstrate, but imagine you would have used DI in the previous example. The code creating all those things might look something like this:



    List<Car> cars = new List<Car>();
    for(int i=0; i<8; i++){
    float acceleration = 0.3f;
    float maxSpeed = 200.0f;
    Motor motor = new Motor(acceleration, maxSpeed);
    Car car = new Car(motor);
    cars.Add(car);
    }
    RaceTrack raceTrack = new RaceTrack(cars);
    Game game = new Game(raceTrack);


    Now you don't have to make any changes in RaceTrack, Game, Car, or Motor. That means two things:




    • the change is easier, because it's all in one place.

    • there's no way to introduce new bugs in classes you don't change!


    Performance considerations




    or does this affect performance as a whole?




    No. But to be completely honest with you, it might.



    However, even in that case, it's such a ridiculously small amount that you don't need to care. If at some point in the future, you have to write code for a tamagotchi with the equivalent of 5Mhz CPU and 2MB RAM, then maybe you might have to care about this.



    In 99.999%* of cases it will have a better performance, because you spent less time fixing bugs and more time improving your resource-heavy algorithms.



    *completely made up number



    Added info: "hard-coded"



    Make no mistake, this is still very much "hard-coded" - the numbers are written directly in the code. Not hard-coded would mean something like storing those values in a text file - e.g. in JSON format - and then reading them from that file.



    In order to do that, you have to add code for reading a file and then parsing JSON. If you consider the example again; in the non-DI version, a Car or a Motor now has to read a file. That doesn't sound like it makes too much sense.



    In the DI version, you would add it to the code setting up the game.






    share|improve this answer














    Why (what's even the issue)?




    Why should I use dependency injection?




    The best mnemonic I found for this is "new is glue": Every time you use new in your code, that code is tied down to that specific implementation. If you repeatedly use new in constructors, you will create a chain of specific implementations. And because you can't "have" an instance of a class without constructing it, you can't separate that chain.



    As an example, imagine you're writing a race car video game. You started with a class Game, which creates a RaceTrack, which creates 8 Cars, which each create a Motor. Now if you want a second type of Car with a different acceleration, you will have to change every class mentioned, except maybe Game.



    Cleaner code




    Is this just for cleaner architecture/code




    Yes.



    However, it might very well seem less clear in this situation, because it's more an example of how to do it. The actual advantage only shows when several classes are involved and is more difficult to demonstrate, but imagine you would have used DI in the previous example. The code creating all those things might look something like this:



    List<Car> cars = new List<Car>();
    for(int i=0; i<8; i++){
    float acceleration = 0.3f;
    float maxSpeed = 200.0f;
    Motor motor = new Motor(acceleration, maxSpeed);
    Car car = new Car(motor);
    cars.Add(car);
    }
    RaceTrack raceTrack = new RaceTrack(cars);
    Game game = new Game(raceTrack);


    Now you don't have to make any changes in RaceTrack, Game, Car, or Motor. That means two things:




    • the change is easier, because it's all in one place.

    • there's no way to introduce new bugs in classes you don't change!


    Performance considerations




    or does this affect performance as a whole?




    No. But to be completely honest with you, it might.



    However, even in that case, it's such a ridiculously small amount that you don't need to care. If at some point in the future, you have to write code for a tamagotchi with the equivalent of 5Mhz CPU and 2MB RAM, then maybe you might have to care about this.



    In 99.999%* of cases it will have a better performance, because you spent less time fixing bugs and more time improving your resource-heavy algorithms.



    *completely made up number



    Added info: "hard-coded"



    Make no mistake, this is still very much "hard-coded" - the numbers are written directly in the code. Not hard-coded would mean something like storing those values in a text file - e.g. in JSON format - and then reading them from that file.



    In order to do that, you have to add code for reading a file and then parsing JSON. If you consider the example again; in the non-DI version, a Car or a Motor now has to read a file. That doesn't sound like it makes too much sense.



    In the DI version, you would add it to the code setting up the game.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited yesterday

























    answered yesterday









    R. Schmitz

    962621




    962621








    • 2




      Ad hard-coded, there is not really that much difference between code and config file. A file bundled with the application is a source even if you read dynamically. Pulling values from code to data files in json or whatever ‘config’ format helps nothing unless the values should be overridden by the user or depend on the environment.
      – Jan Hudec
      12 hours ago








    • 1




      I actually made a Tamagotchi once on an Arduino (16MHz, 2KB)
      – Jungkook
      11 hours ago










    • @JanHudec True. I actually had a longer explanation there, but decided to remove it to keep it shorter and focus on how it relates to DI. There's more stuff which isn't 100% correct; overall the answer is more optimized to push "the point" of DI without it getting too long. Or put differently, this is what I would have wanted to hear when I started out with DI.
      – R. Schmitz
      8 hours ago














    • 2




      Ad hard-coded, there is not really that much difference between code and config file. A file bundled with the application is a source even if you read dynamically. Pulling values from code to data files in json or whatever ‘config’ format helps nothing unless the values should be overridden by the user or depend on the environment.
      – Jan Hudec
      12 hours ago








    • 1




      I actually made a Tamagotchi once on an Arduino (16MHz, 2KB)
      – Jungkook
      11 hours ago










    • @JanHudec True. I actually had a longer explanation there, but decided to remove it to keep it shorter and focus on how it relates to DI. There's more stuff which isn't 100% correct; overall the answer is more optimized to push "the point" of DI without it getting too long. Or put differently, this is what I would have wanted to hear when I started out with DI.
      – R. Schmitz
      8 hours ago








    2




    2




    Ad hard-coded, there is not really that much difference between code and config file. A file bundled with the application is a source even if you read dynamically. Pulling values from code to data files in json or whatever ‘config’ format helps nothing unless the values should be overridden by the user or depend on the environment.
    – Jan Hudec
    12 hours ago






    Ad hard-coded, there is not really that much difference between code and config file. A file bundled with the application is a source even if you read dynamically. Pulling values from code to data files in json or whatever ‘config’ format helps nothing unless the values should be overridden by the user or depend on the environment.
    – Jan Hudec
    12 hours ago






    1




    1




    I actually made a Tamagotchi once on an Arduino (16MHz, 2KB)
    – Jungkook
    11 hours ago




    I actually made a Tamagotchi once on an Arduino (16MHz, 2KB)
    – Jungkook
    11 hours ago












    @JanHudec True. I actually had a longer explanation there, but decided to remove it to keep it shorter and focus on how it relates to DI. There's more stuff which isn't 100% correct; overall the answer is more optimized to push "the point" of DI without it getting too long. Or put differently, this is what I would have wanted to hear when I started out with DI.
    – R. Schmitz
    8 hours ago




    @JanHudec True. I actually had a longer explanation there, but decided to remove it to keep it shorter and focus on how it relates to DI. There's more stuff which isn't 100% correct; overall the answer is more optimized to push "the point" of DI without it getting too long. Or put differently, this is what I would have wanted to hear when I started out with DI.
    – R. Schmitz
    8 hours ago










    up vote
    5
    down vote













    The example you give is not dependency injection in the classical sense. Dependency injection usually refers to passing objects in a constructor or by using "setter injection" just after the object is created, in order to set a value on a field in a newly created object.



    Your example passes an object as an argument to an instance method. This instance method then modifies a field on that object. Dependency injection? No. Breaking encapsulation and data hiding? Absolutely!



    Now, if the code was like this:



    class Profile {
    private $settings;

    public function __construct(Settings $settings) {
    $this->settings = $settings;
    }

    public function deactive() {
    $this->settings->isActive = false;
    }
    }


    Then I would say you are using dependency injection. The notable difference is a Settings object being passed in to the constructor or a Profile object.



    This is useful if the Settings object is expensive or complex to construct, or Settings is an interface or abstract class where multiple concrete implementations exist in order to change run time behavior.



    Since you are directly accessing a field on the Settings object rather than calling a method, you can't take advantage of Polymorphism, which is one of the benefits of dependency injection.



    It looks like the Settings for a Profile are specific to that profile. In this case I would do one of the following:




    1. Instantiate the Settings object inside the Profile constructor


    2. Pass the Settings object in the constructor and copy over individual fields that apply to the Profile



    Honestly, by passing the Settings object in to deactivateProfile and then modifying an internal field of the Settings object is a code smell. The Settings object should be the only one modifying its internal fields.






    share|improve this answer

















    • 5




      The example you give is not dependency injection in the classical sense. -- It doesn't matter. OO people have objects on the brain, but you're still handing a dependency to something.
      – Robert Harvey
      yesterday










    • When you talk about “in the classical sense”, you are, as @RobertHarvey says, speaking purely in OO terms. In functional programming for example, injecting one function into another (higher order functions) is that paradigm’s classical example of dependency injection.
      – David Arno
      yesterday






    • 2




      @RobertHarvey: I guess I was taking too many liberties with "dependency injection." The place people most often think of the term and use the term is in reference to fields on an object being "injected" at the time of object construction, or immediately after in the case of setter injection.
      – Greg Burghardt
      yesterday










    • @DavidArno: Yes, you are correct. The OP seems to have an object oriented PHP code snippet in the question, so I was answering in that regard only, and not addressing functional programming --- all though with PHP you could ask the same question from the standpoint of functional programming.
      – Greg Burghardt
      yesterday















    up vote
    5
    down vote













    The example you give is not dependency injection in the classical sense. Dependency injection usually refers to passing objects in a constructor or by using "setter injection" just after the object is created, in order to set a value on a field in a newly created object.



    Your example passes an object as an argument to an instance method. This instance method then modifies a field on that object. Dependency injection? No. Breaking encapsulation and data hiding? Absolutely!



    Now, if the code was like this:



    class Profile {
    private $settings;

    public function __construct(Settings $settings) {
    $this->settings = $settings;
    }

    public function deactive() {
    $this->settings->isActive = false;
    }
    }


    Then I would say you are using dependency injection. The notable difference is a Settings object being passed in to the constructor or a Profile object.



    This is useful if the Settings object is expensive or complex to construct, or Settings is an interface or abstract class where multiple concrete implementations exist in order to change run time behavior.



    Since you are directly accessing a field on the Settings object rather than calling a method, you can't take advantage of Polymorphism, which is one of the benefits of dependency injection.



    It looks like the Settings for a Profile are specific to that profile. In this case I would do one of the following:




    1. Instantiate the Settings object inside the Profile constructor


    2. Pass the Settings object in the constructor and copy over individual fields that apply to the Profile



    Honestly, by passing the Settings object in to deactivateProfile and then modifying an internal field of the Settings object is a code smell. The Settings object should be the only one modifying its internal fields.






    share|improve this answer

















    • 5




      The example you give is not dependency injection in the classical sense. -- It doesn't matter. OO people have objects on the brain, but you're still handing a dependency to something.
      – Robert Harvey
      yesterday










    • When you talk about “in the classical sense”, you are, as @RobertHarvey says, speaking purely in OO terms. In functional programming for example, injecting one function into another (higher order functions) is that paradigm’s classical example of dependency injection.
      – David Arno
      yesterday






    • 2




      @RobertHarvey: I guess I was taking too many liberties with "dependency injection." The place people most often think of the term and use the term is in reference to fields on an object being "injected" at the time of object construction, or immediately after in the case of setter injection.
      – Greg Burghardt
      yesterday










    • @DavidArno: Yes, you are correct. The OP seems to have an object oriented PHP code snippet in the question, so I was answering in that regard only, and not addressing functional programming --- all though with PHP you could ask the same question from the standpoint of functional programming.
      – Greg Burghardt
      yesterday













    up vote
    5
    down vote










    up vote
    5
    down vote









    The example you give is not dependency injection in the classical sense. Dependency injection usually refers to passing objects in a constructor or by using "setter injection" just after the object is created, in order to set a value on a field in a newly created object.



    Your example passes an object as an argument to an instance method. This instance method then modifies a field on that object. Dependency injection? No. Breaking encapsulation and data hiding? Absolutely!



    Now, if the code was like this:



    class Profile {
    private $settings;

    public function __construct(Settings $settings) {
    $this->settings = $settings;
    }

    public function deactive() {
    $this->settings->isActive = false;
    }
    }


    Then I would say you are using dependency injection. The notable difference is a Settings object being passed in to the constructor or a Profile object.



    This is useful if the Settings object is expensive or complex to construct, or Settings is an interface or abstract class where multiple concrete implementations exist in order to change run time behavior.



    Since you are directly accessing a field on the Settings object rather than calling a method, you can't take advantage of Polymorphism, which is one of the benefits of dependency injection.



    It looks like the Settings for a Profile are specific to that profile. In this case I would do one of the following:




    1. Instantiate the Settings object inside the Profile constructor


    2. Pass the Settings object in the constructor and copy over individual fields that apply to the Profile



    Honestly, by passing the Settings object in to deactivateProfile and then modifying an internal field of the Settings object is a code smell. The Settings object should be the only one modifying its internal fields.






    share|improve this answer












    The example you give is not dependency injection in the classical sense. Dependency injection usually refers to passing objects in a constructor or by using "setter injection" just after the object is created, in order to set a value on a field in a newly created object.



    Your example passes an object as an argument to an instance method. This instance method then modifies a field on that object. Dependency injection? No. Breaking encapsulation and data hiding? Absolutely!



    Now, if the code was like this:



    class Profile {
    private $settings;

    public function __construct(Settings $settings) {
    $this->settings = $settings;
    }

    public function deactive() {
    $this->settings->isActive = false;
    }
    }


    Then I would say you are using dependency injection. The notable difference is a Settings object being passed in to the constructor or a Profile object.



    This is useful if the Settings object is expensive or complex to construct, or Settings is an interface or abstract class where multiple concrete implementations exist in order to change run time behavior.



    Since you are directly accessing a field on the Settings object rather than calling a method, you can't take advantage of Polymorphism, which is one of the benefits of dependency injection.



    It looks like the Settings for a Profile are specific to that profile. In this case I would do one of the following:




    1. Instantiate the Settings object inside the Profile constructor


    2. Pass the Settings object in the constructor and copy over individual fields that apply to the Profile



    Honestly, by passing the Settings object in to deactivateProfile and then modifying an internal field of the Settings object is a code smell. The Settings object should be the only one modifying its internal fields.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered yesterday









    Greg Burghardt

    11.2k42755




    11.2k42755








    • 5




      The example you give is not dependency injection in the classical sense. -- It doesn't matter. OO people have objects on the brain, but you're still handing a dependency to something.
      – Robert Harvey
      yesterday










    • When you talk about “in the classical sense”, you are, as @RobertHarvey says, speaking purely in OO terms. In functional programming for example, injecting one function into another (higher order functions) is that paradigm’s classical example of dependency injection.
      – David Arno
      yesterday






    • 2




      @RobertHarvey: I guess I was taking too many liberties with "dependency injection." The place people most often think of the term and use the term is in reference to fields on an object being "injected" at the time of object construction, or immediately after in the case of setter injection.
      – Greg Burghardt
      yesterday










    • @DavidArno: Yes, you are correct. The OP seems to have an object oriented PHP code snippet in the question, so I was answering in that regard only, and not addressing functional programming --- all though with PHP you could ask the same question from the standpoint of functional programming.
      – Greg Burghardt
      yesterday














    • 5




      The example you give is not dependency injection in the classical sense. -- It doesn't matter. OO people have objects on the brain, but you're still handing a dependency to something.
      – Robert Harvey
      yesterday










    • When you talk about “in the classical sense”, you are, as @RobertHarvey says, speaking purely in OO terms. In functional programming for example, injecting one function into another (higher order functions) is that paradigm’s classical example of dependency injection.
      – David Arno
      yesterday






    • 2




      @RobertHarvey: I guess I was taking too many liberties with "dependency injection." The place people most often think of the term and use the term is in reference to fields on an object being "injected" at the time of object construction, or immediately after in the case of setter injection.
      – Greg Burghardt
      yesterday










    • @DavidArno: Yes, you are correct. The OP seems to have an object oriented PHP code snippet in the question, so I was answering in that regard only, and not addressing functional programming --- all though with PHP you could ask the same question from the standpoint of functional programming.
      – Greg Burghardt
      yesterday








    5




    5




    The example you give is not dependency injection in the classical sense. -- It doesn't matter. OO people have objects on the brain, but you're still handing a dependency to something.
    – Robert Harvey
    yesterday




    The example you give is not dependency injection in the classical sense. -- It doesn't matter. OO people have objects on the brain, but you're still handing a dependency to something.
    – Robert Harvey
    yesterday












    When you talk about “in the classical sense”, you are, as @RobertHarvey says, speaking purely in OO terms. In functional programming for example, injecting one function into another (higher order functions) is that paradigm’s classical example of dependency injection.
    – David Arno
    yesterday




    When you talk about “in the classical sense”, you are, as @RobertHarvey says, speaking purely in OO terms. In functional programming for example, injecting one function into another (higher order functions) is that paradigm’s classical example of dependency injection.
    – David Arno
    yesterday




    2




    2




    @RobertHarvey: I guess I was taking too many liberties with "dependency injection." The place people most often think of the term and use the term is in reference to fields on an object being "injected" at the time of object construction, or immediately after in the case of setter injection.
    – Greg Burghardt
    yesterday




    @RobertHarvey: I guess I was taking too many liberties with "dependency injection." The place people most often think of the term and use the term is in reference to fields on an object being "injected" at the time of object construction, or immediately after in the case of setter injection.
    – Greg Burghardt
    yesterday












    @DavidArno: Yes, you are correct. The OP seems to have an object oriented PHP code snippet in the question, so I was answering in that regard only, and not addressing functional programming --- all though with PHP you could ask the same question from the standpoint of functional programming.
    – Greg Burghardt
    yesterday




    @DavidArno: Yes, you are correct. The OP seems to have an object oriented PHP code snippet in the question, so I was answering in that regard only, and not addressing functional programming --- all though with PHP you could ask the same question from the standpoint of functional programming.
    – Greg Burghardt
    yesterday










    up vote
    2
    down vote













    I know I'm coming late to this party but I feel an important point is being missed.




    Why should I do this:




    class Profile {
    public function deactivateProfile(Setting $setting)
    {
    $setting->isActive = false;
    }
    }


    You shouldn't. But not because Dependency Injection is a bad idea. It's because this is doing it wrong.



    Lets look at this things using code. We're going to do this:



    $profile = new Profile();
    $profile->deactivateProfile($setting);


    when we get about the same thing out of this:



    $setting->isActive = false; // Deactivate profile


    So of course it seems like a waste of time. It is when you do it this way. This is not the best use of Dependency Injection. It's not even the best use of a class.



    Now what if instead we had this:



    $profile = new Profile($setting);

    $application = new Application($profile);

    $application.start();


    And now the application is free to activate and deactivate the profile without having to know anything in particular about the setting that it's actually changing. Why is that good? In case you need to change setting. The application is walled off from those changes so you're free to go nuts in a safe contained space without having to watch everything break as soon as you touch something.



    This follows the separate construction from behavior principle. The DI pattern here is a simple one. Build everything you need at as low a level as you can, wire them together, then start all the behavior ticking with one call.



    The result is you have a separate place to decide what connects to what and a different place to manage what says what to whatever.



    If that's not helpful to you then sure. DI, classes, object oriented programming, it's all a useless waste of time. Procedural code can solve all the same problems with less code.



    Being able to make places in the code where I only have to think about a few things at the same time has really proved useful to me over the years. Sure it takes effort to make them. But once they're made I find working with them very relaxing. The people who maintain my code after I leave seem to like them too.



    I know because I take the time to go back and visit my creations years later. You should to.






    share|improve this answer























    • I was ready to upvote this until I got to the last three paragraphs, which come across as a bit patronising, or maybe just pessimistic. It's like you're assuming that the reader will ignore everything you've just said, and defensively responding to comments that haven't been made yet.
      – IMSoP
      3 hours ago















    up vote
    2
    down vote













    I know I'm coming late to this party but I feel an important point is being missed.




    Why should I do this:




    class Profile {
    public function deactivateProfile(Setting $setting)
    {
    $setting->isActive = false;
    }
    }


    You shouldn't. But not because Dependency Injection is a bad idea. It's because this is doing it wrong.



    Lets look at this things using code. We're going to do this:



    $profile = new Profile();
    $profile->deactivateProfile($setting);


    when we get about the same thing out of this:



    $setting->isActive = false; // Deactivate profile


    So of course it seems like a waste of time. It is when you do it this way. This is not the best use of Dependency Injection. It's not even the best use of a class.



    Now what if instead we had this:



    $profile = new Profile($setting);

    $application = new Application($profile);

    $application.start();


    And now the application is free to activate and deactivate the profile without having to know anything in particular about the setting that it's actually changing. Why is that good? In case you need to change setting. The application is walled off from those changes so you're free to go nuts in a safe contained space without having to watch everything break as soon as you touch something.



    This follows the separate construction from behavior principle. The DI pattern here is a simple one. Build everything you need at as low a level as you can, wire them together, then start all the behavior ticking with one call.



    The result is you have a separate place to decide what connects to what and a different place to manage what says what to whatever.



    If that's not helpful to you then sure. DI, classes, object oriented programming, it's all a useless waste of time. Procedural code can solve all the same problems with less code.



    Being able to make places in the code where I only have to think about a few things at the same time has really proved useful to me over the years. Sure it takes effort to make them. But once they're made I find working with them very relaxing. The people who maintain my code after I leave seem to like them too.



    I know because I take the time to go back and visit my creations years later. You should to.






    share|improve this answer























    • I was ready to upvote this until I got to the last three paragraphs, which come across as a bit patronising, or maybe just pessimistic. It's like you're assuming that the reader will ignore everything you've just said, and defensively responding to comments that haven't been made yet.
      – IMSoP
      3 hours ago













    up vote
    2
    down vote










    up vote
    2
    down vote









    I know I'm coming late to this party but I feel an important point is being missed.




    Why should I do this:




    class Profile {
    public function deactivateProfile(Setting $setting)
    {
    $setting->isActive = false;
    }
    }


    You shouldn't. But not because Dependency Injection is a bad idea. It's because this is doing it wrong.



    Lets look at this things using code. We're going to do this:



    $profile = new Profile();
    $profile->deactivateProfile($setting);


    when we get about the same thing out of this:



    $setting->isActive = false; // Deactivate profile


    So of course it seems like a waste of time. It is when you do it this way. This is not the best use of Dependency Injection. It's not even the best use of a class.



    Now what if instead we had this:



    $profile = new Profile($setting);

    $application = new Application($profile);

    $application.start();


    And now the application is free to activate and deactivate the profile without having to know anything in particular about the setting that it's actually changing. Why is that good? In case you need to change setting. The application is walled off from those changes so you're free to go nuts in a safe contained space without having to watch everything break as soon as you touch something.



    This follows the separate construction from behavior principle. The DI pattern here is a simple one. Build everything you need at as low a level as you can, wire them together, then start all the behavior ticking with one call.



    The result is you have a separate place to decide what connects to what and a different place to manage what says what to whatever.



    If that's not helpful to you then sure. DI, classes, object oriented programming, it's all a useless waste of time. Procedural code can solve all the same problems with less code.



    Being able to make places in the code where I only have to think about a few things at the same time has really proved useful to me over the years. Sure it takes effort to make them. But once they're made I find working with them very relaxing. The people who maintain my code after I leave seem to like them too.



    I know because I take the time to go back and visit my creations years later. You should to.






    share|improve this answer














    I know I'm coming late to this party but I feel an important point is being missed.




    Why should I do this:




    class Profile {
    public function deactivateProfile(Setting $setting)
    {
    $setting->isActive = false;
    }
    }


    You shouldn't. But not because Dependency Injection is a bad idea. It's because this is doing it wrong.



    Lets look at this things using code. We're going to do this:



    $profile = new Profile();
    $profile->deactivateProfile($setting);


    when we get about the same thing out of this:



    $setting->isActive = false; // Deactivate profile


    So of course it seems like a waste of time. It is when you do it this way. This is not the best use of Dependency Injection. It's not even the best use of a class.



    Now what if instead we had this:



    $profile = new Profile($setting);

    $application = new Application($profile);

    $application.start();


    And now the application is free to activate and deactivate the profile without having to know anything in particular about the setting that it's actually changing. Why is that good? In case you need to change setting. The application is walled off from those changes so you're free to go nuts in a safe contained space without having to watch everything break as soon as you touch something.



    This follows the separate construction from behavior principle. The DI pattern here is a simple one. Build everything you need at as low a level as you can, wire them together, then start all the behavior ticking with one call.



    The result is you have a separate place to decide what connects to what and a different place to manage what says what to whatever.



    If that's not helpful to you then sure. DI, classes, object oriented programming, it's all a useless waste of time. Procedural code can solve all the same problems with less code.



    Being able to make places in the code where I only have to think about a few things at the same time has really proved useful to me over the years. Sure it takes effort to make them. But once they're made I find working with them very relaxing. The people who maintain my code after I leave seem to like them too.



    I know because I take the time to go back and visit my creations years later. You should to.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 19 hours ago

























    answered 23 hours ago









    candied_orange

    49.4k1686173




    49.4k1686173












    • I was ready to upvote this until I got to the last three paragraphs, which come across as a bit patronising, or maybe just pessimistic. It's like you're assuming that the reader will ignore everything you've just said, and defensively responding to comments that haven't been made yet.
      – IMSoP
      3 hours ago


















    • I was ready to upvote this until I got to the last three paragraphs, which come across as a bit patronising, or maybe just pessimistic. It's like you're assuming that the reader will ignore everything you've just said, and defensively responding to comments that haven't been made yet.
      – IMSoP
      3 hours ago
















    I was ready to upvote this until I got to the last three paragraphs, which come across as a bit patronising, or maybe just pessimistic. It's like you're assuming that the reader will ignore everything you've just said, and defensively responding to comments that haven't been made yet.
    – IMSoP
    3 hours ago




    I was ready to upvote this until I got to the last three paragraphs, which come across as a bit patronising, or maybe just pessimistic. It's like you're assuming that the reader will ignore everything you've just said, and defensively responding to comments that haven't been made yet.
    – IMSoP
    3 hours ago










    up vote
    0
    down vote













    You should use techniques to solve the problems they're good at solving when you have those problems. Dependency inversion and injection are no different.



    Dependency inversion or injection is a technique that allows your code to decide on what implementation of a method gets called at run time. This maximizes the benefits of late binding. The technique is necessary when the language does not support run time replacement of non-instance functions. For example, Java lacks a mechanism to replace calls to a static method with calls to a different implementation; contrast with Python, where all that's necessary to replace the function call is to bind the name to a different function (reassign the variable holding the function).



    Why would we want to vary the implementation of the function? There's a two main reasons:




    • We want to use fakes for testing purposes. This allows us to test a class that depends on a database fetch without actually connecting to the database.

    • We need to support multiple implementations. For example, we might need to set up a system that supports both MySQL and PostgreSQL databases.


    You may also want to take note of inversion of control containers. This is a technique that is intended to help you avoid huge, tangled construction trees that look like this pseudocode:



    thing5 =  new MyThing5();
    thing3 = new MyThing3(thing5, new MyThing10());

    myApp = new MyApp(
    new MyAppDependency1(thing5, thing3),
    new MyAppDependency2(
    new Thing1(),
    new Thing2(new Thing3(thing5, new Thing4(thing5)))
    ),
    ...
    new MyAppDependency15(thing5)
    );


    It lets you register your classes and then does the construction for you:



    injector.register(Thing1); // Yes, you'd need some kind of actual class reference.
    injector.register(Thing2);
    ...
    injector.register(MyAppDepdency15);
    injector.register(MyApp);

    myApp = injector.create(MyApp); // The injector fills in all the construction parameters.


    Note that it's simplest if the classes registered can be stateless singletons.



    Word of caution



    Note that dependency inversion should not be your go-to answer for decoupling logic. Look for opportunities to use parameterization instead. Consider this pseudocode method for example:



    myAverageAboveMin()
    {
    dbConn = new DbConnection("my connection string");
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", 5);
    dbQuery.Execute();
    myData = dbQuery.getAll();
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }


    We could use dependency inversion for some parts of this method:



    class MyQuerier
    {
    private _dbConn;

    MyQueries(dbConn) { this._dbConn = dbConn; }

    fetchAboveMin(min)
    {
    dbQuery = this._dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", min);
    dbQuery.Execute();
    return dbQuery.getAll();
    }
    }


    class Averager
    {
    private _querier;

    Averager(querier) { this._querier = querier; }

    myAverageAboveMin(min)
    {
    myData = this._querier.fetchAboveMin(min);
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }


    But we shouldn't, at least not completely. Notice that we've created a stateful class with Querier. It now holds a reference to some essentially global connection object. This creates problems such as difficulty in understanding the overall state of the program and how different classes coordinate with each other. Notice also that we're forced to fake out the querier or the connection if we want to test the averaging logic. Further A better approach would be to increase parameterization:



    class MyQuerier
    {
    fetchAboveMin(dbConn, min)
    {
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", min);
    dbQuery.Execute();
    return dbQuery.getAll();
    }
    }


    class Averager
    {
    averageData(myData)
    {
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }

    class StuffDoer
    {
    private _querier;
    private _averager;

    StuffDoer(querier, averager)
    {
    this._querier = querier;
    this._averager = averager;
    }

    myAverageAboveMin(dbConn, min)
    {
    myData = this._querier.fetchAboveMin(dbConn, min);
    return this._averager.averageData(myData);
    }
    }


    And the connection would be managed at some even higher level that's responsible for the operation as a whole and knows what to do with this output.



    Now we can test the averaging logic completely independently of the querying, and what's more we can use it in a wider variety of situations. We might question whether we even need the MyQuerier and Averager objects, and maybe the answer is that we don't if we don't intend to unit test StuffDoer, and not unit testing StuffDoer would be perfectly reasonable since it's so tightly coupled to the database. It might make more sense to just let integration tests cover it. In that case, we might be fine making fetchAboveMin and averageData into static methods.






    share|improve this answer



















    • 1




      "Dependency injection is a technique that is intended to help you avoid huge, tangled construction trees...". Your first example after this claim is an example of pure, or poor man's, dependency injection. The second is an example of using an IoC container to "automate" the injection of those dependencies. Both are examples of dependency injection in action.
      – David Arno
      yesterday










    • @DavidArno Yeah, you're right. I've adjusted the terminology.
      – jpmc26
      yesterday















    up vote
    0
    down vote













    You should use techniques to solve the problems they're good at solving when you have those problems. Dependency inversion and injection are no different.



    Dependency inversion or injection is a technique that allows your code to decide on what implementation of a method gets called at run time. This maximizes the benefits of late binding. The technique is necessary when the language does not support run time replacement of non-instance functions. For example, Java lacks a mechanism to replace calls to a static method with calls to a different implementation; contrast with Python, where all that's necessary to replace the function call is to bind the name to a different function (reassign the variable holding the function).



    Why would we want to vary the implementation of the function? There's a two main reasons:




    • We want to use fakes for testing purposes. This allows us to test a class that depends on a database fetch without actually connecting to the database.

    • We need to support multiple implementations. For example, we might need to set up a system that supports both MySQL and PostgreSQL databases.


    You may also want to take note of inversion of control containers. This is a technique that is intended to help you avoid huge, tangled construction trees that look like this pseudocode:



    thing5 =  new MyThing5();
    thing3 = new MyThing3(thing5, new MyThing10());

    myApp = new MyApp(
    new MyAppDependency1(thing5, thing3),
    new MyAppDependency2(
    new Thing1(),
    new Thing2(new Thing3(thing5, new Thing4(thing5)))
    ),
    ...
    new MyAppDependency15(thing5)
    );


    It lets you register your classes and then does the construction for you:



    injector.register(Thing1); // Yes, you'd need some kind of actual class reference.
    injector.register(Thing2);
    ...
    injector.register(MyAppDepdency15);
    injector.register(MyApp);

    myApp = injector.create(MyApp); // The injector fills in all the construction parameters.


    Note that it's simplest if the classes registered can be stateless singletons.



    Word of caution



    Note that dependency inversion should not be your go-to answer for decoupling logic. Look for opportunities to use parameterization instead. Consider this pseudocode method for example:



    myAverageAboveMin()
    {
    dbConn = new DbConnection("my connection string");
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", 5);
    dbQuery.Execute();
    myData = dbQuery.getAll();
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }


    We could use dependency inversion for some parts of this method:



    class MyQuerier
    {
    private _dbConn;

    MyQueries(dbConn) { this._dbConn = dbConn; }

    fetchAboveMin(min)
    {
    dbQuery = this._dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", min);
    dbQuery.Execute();
    return dbQuery.getAll();
    }
    }


    class Averager
    {
    private _querier;

    Averager(querier) { this._querier = querier; }

    myAverageAboveMin(min)
    {
    myData = this._querier.fetchAboveMin(min);
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }


    But we shouldn't, at least not completely. Notice that we've created a stateful class with Querier. It now holds a reference to some essentially global connection object. This creates problems such as difficulty in understanding the overall state of the program and how different classes coordinate with each other. Notice also that we're forced to fake out the querier or the connection if we want to test the averaging logic. Further A better approach would be to increase parameterization:



    class MyQuerier
    {
    fetchAboveMin(dbConn, min)
    {
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", min);
    dbQuery.Execute();
    return dbQuery.getAll();
    }
    }


    class Averager
    {
    averageData(myData)
    {
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }

    class StuffDoer
    {
    private _querier;
    private _averager;

    StuffDoer(querier, averager)
    {
    this._querier = querier;
    this._averager = averager;
    }

    myAverageAboveMin(dbConn, min)
    {
    myData = this._querier.fetchAboveMin(dbConn, min);
    return this._averager.averageData(myData);
    }
    }


    And the connection would be managed at some even higher level that's responsible for the operation as a whole and knows what to do with this output.



    Now we can test the averaging logic completely independently of the querying, and what's more we can use it in a wider variety of situations. We might question whether we even need the MyQuerier and Averager objects, and maybe the answer is that we don't if we don't intend to unit test StuffDoer, and not unit testing StuffDoer would be perfectly reasonable since it's so tightly coupled to the database. It might make more sense to just let integration tests cover it. In that case, we might be fine making fetchAboveMin and averageData into static methods.






    share|improve this answer



















    • 1




      "Dependency injection is a technique that is intended to help you avoid huge, tangled construction trees...". Your first example after this claim is an example of pure, or poor man's, dependency injection. The second is an example of using an IoC container to "automate" the injection of those dependencies. Both are examples of dependency injection in action.
      – David Arno
      yesterday










    • @DavidArno Yeah, you're right. I've adjusted the terminology.
      – jpmc26
      yesterday













    up vote
    0
    down vote










    up vote
    0
    down vote









    You should use techniques to solve the problems they're good at solving when you have those problems. Dependency inversion and injection are no different.



    Dependency inversion or injection is a technique that allows your code to decide on what implementation of a method gets called at run time. This maximizes the benefits of late binding. The technique is necessary when the language does not support run time replacement of non-instance functions. For example, Java lacks a mechanism to replace calls to a static method with calls to a different implementation; contrast with Python, where all that's necessary to replace the function call is to bind the name to a different function (reassign the variable holding the function).



    Why would we want to vary the implementation of the function? There's a two main reasons:




    • We want to use fakes for testing purposes. This allows us to test a class that depends on a database fetch without actually connecting to the database.

    • We need to support multiple implementations. For example, we might need to set up a system that supports both MySQL and PostgreSQL databases.


    You may also want to take note of inversion of control containers. This is a technique that is intended to help you avoid huge, tangled construction trees that look like this pseudocode:



    thing5 =  new MyThing5();
    thing3 = new MyThing3(thing5, new MyThing10());

    myApp = new MyApp(
    new MyAppDependency1(thing5, thing3),
    new MyAppDependency2(
    new Thing1(),
    new Thing2(new Thing3(thing5, new Thing4(thing5)))
    ),
    ...
    new MyAppDependency15(thing5)
    );


    It lets you register your classes and then does the construction for you:



    injector.register(Thing1); // Yes, you'd need some kind of actual class reference.
    injector.register(Thing2);
    ...
    injector.register(MyAppDepdency15);
    injector.register(MyApp);

    myApp = injector.create(MyApp); // The injector fills in all the construction parameters.


    Note that it's simplest if the classes registered can be stateless singletons.



    Word of caution



    Note that dependency inversion should not be your go-to answer for decoupling logic. Look for opportunities to use parameterization instead. Consider this pseudocode method for example:



    myAverageAboveMin()
    {
    dbConn = new DbConnection("my connection string");
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", 5);
    dbQuery.Execute();
    myData = dbQuery.getAll();
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }


    We could use dependency inversion for some parts of this method:



    class MyQuerier
    {
    private _dbConn;

    MyQueries(dbConn) { this._dbConn = dbConn; }

    fetchAboveMin(min)
    {
    dbQuery = this._dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", min);
    dbQuery.Execute();
    return dbQuery.getAll();
    }
    }


    class Averager
    {
    private _querier;

    Averager(querier) { this._querier = querier; }

    myAverageAboveMin(min)
    {
    myData = this._querier.fetchAboveMin(min);
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }


    But we shouldn't, at least not completely. Notice that we've created a stateful class with Querier. It now holds a reference to some essentially global connection object. This creates problems such as difficulty in understanding the overall state of the program and how different classes coordinate with each other. Notice also that we're forced to fake out the querier or the connection if we want to test the averaging logic. Further A better approach would be to increase parameterization:



    class MyQuerier
    {
    fetchAboveMin(dbConn, min)
    {
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", min);
    dbQuery.Execute();
    return dbQuery.getAll();
    }
    }


    class Averager
    {
    averageData(myData)
    {
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }

    class StuffDoer
    {
    private _querier;
    private _averager;

    StuffDoer(querier, averager)
    {
    this._querier = querier;
    this._averager = averager;
    }

    myAverageAboveMin(dbConn, min)
    {
    myData = this._querier.fetchAboveMin(dbConn, min);
    return this._averager.averageData(myData);
    }
    }


    And the connection would be managed at some even higher level that's responsible for the operation as a whole and knows what to do with this output.



    Now we can test the averaging logic completely independently of the querying, and what's more we can use it in a wider variety of situations. We might question whether we even need the MyQuerier and Averager objects, and maybe the answer is that we don't if we don't intend to unit test StuffDoer, and not unit testing StuffDoer would be perfectly reasonable since it's so tightly coupled to the database. It might make more sense to just let integration tests cover it. In that case, we might be fine making fetchAboveMin and averageData into static methods.






    share|improve this answer














    You should use techniques to solve the problems they're good at solving when you have those problems. Dependency inversion and injection are no different.



    Dependency inversion or injection is a technique that allows your code to decide on what implementation of a method gets called at run time. This maximizes the benefits of late binding. The technique is necessary when the language does not support run time replacement of non-instance functions. For example, Java lacks a mechanism to replace calls to a static method with calls to a different implementation; contrast with Python, where all that's necessary to replace the function call is to bind the name to a different function (reassign the variable holding the function).



    Why would we want to vary the implementation of the function? There's a two main reasons:




    • We want to use fakes for testing purposes. This allows us to test a class that depends on a database fetch without actually connecting to the database.

    • We need to support multiple implementations. For example, we might need to set up a system that supports both MySQL and PostgreSQL databases.


    You may also want to take note of inversion of control containers. This is a technique that is intended to help you avoid huge, tangled construction trees that look like this pseudocode:



    thing5 =  new MyThing5();
    thing3 = new MyThing3(thing5, new MyThing10());

    myApp = new MyApp(
    new MyAppDependency1(thing5, thing3),
    new MyAppDependency2(
    new Thing1(),
    new Thing2(new Thing3(thing5, new Thing4(thing5)))
    ),
    ...
    new MyAppDependency15(thing5)
    );


    It lets you register your classes and then does the construction for you:



    injector.register(Thing1); // Yes, you'd need some kind of actual class reference.
    injector.register(Thing2);
    ...
    injector.register(MyAppDepdency15);
    injector.register(MyApp);

    myApp = injector.create(MyApp); // The injector fills in all the construction parameters.


    Note that it's simplest if the classes registered can be stateless singletons.



    Word of caution



    Note that dependency inversion should not be your go-to answer for decoupling logic. Look for opportunities to use parameterization instead. Consider this pseudocode method for example:



    myAverageAboveMin()
    {
    dbConn = new DbConnection("my connection string");
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", 5);
    dbQuery.Execute();
    myData = dbQuery.getAll();
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }


    We could use dependency inversion for some parts of this method:



    class MyQuerier
    {
    private _dbConn;

    MyQueries(dbConn) { this._dbConn = dbConn; }

    fetchAboveMin(min)
    {
    dbQuery = this._dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", min);
    dbQuery.Execute();
    return dbQuery.getAll();
    }
    }


    class Averager
    {
    private _querier;

    Averager(querier) { this._querier = querier; }

    myAverageAboveMin(min)
    {
    myData = this._querier.fetchAboveMin(min);
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }


    But we shouldn't, at least not completely. Notice that we've created a stateful class with Querier. It now holds a reference to some essentially global connection object. This creates problems such as difficulty in understanding the overall state of the program and how different classes coordinate with each other. Notice also that we're forced to fake out the querier or the connection if we want to test the averaging logic. Further A better approach would be to increase parameterization:



    class MyQuerier
    {
    fetchAboveMin(dbConn, min)
    {
    dbQuery = dbConn.makeQuery();
    dbQuery.Command = "SELECT * FROM MY_DATA WHERE x > :min";
    dbQuery.setParam("min", min);
    dbQuery.Execute();
    return dbQuery.getAll();
    }
    }


    class Averager
    {
    averageData(myData)
    {
    count = 0;
    total = 0;
    foreach (row in myData)
    {
    count++;
    total += row.x;
    }

    return total / count;
    }

    class StuffDoer
    {
    private _querier;
    private _averager;

    StuffDoer(querier, averager)
    {
    this._querier = querier;
    this._averager = averager;
    }

    myAverageAboveMin(dbConn, min)
    {
    myData = this._querier.fetchAboveMin(dbConn, min);
    return this._averager.averageData(myData);
    }
    }


    And the connection would be managed at some even higher level that's responsible for the operation as a whole and knows what to do with this output.



    Now we can test the averaging logic completely independently of the querying, and what's more we can use it in a wider variety of situations. We might question whether we even need the MyQuerier and Averager objects, and maybe the answer is that we don't if we don't intend to unit test StuffDoer, and not unit testing StuffDoer would be perfectly reasonable since it's so tightly coupled to the database. It might make more sense to just let integration tests cover it. In that case, we might be fine making fetchAboveMin and averageData into static methods.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited yesterday

























    answered yesterday









    jpmc26

    3,82111735




    3,82111735








    • 1




      "Dependency injection is a technique that is intended to help you avoid huge, tangled construction trees...". Your first example after this claim is an example of pure, or poor man's, dependency injection. The second is an example of using an IoC container to "automate" the injection of those dependencies. Both are examples of dependency injection in action.
      – David Arno
      yesterday










    • @DavidArno Yeah, you're right. I've adjusted the terminology.
      – jpmc26
      yesterday














    • 1




      "Dependency injection is a technique that is intended to help you avoid huge, tangled construction trees...". Your first example after this claim is an example of pure, or poor man's, dependency injection. The second is an example of using an IoC container to "automate" the injection of those dependencies. Both are examples of dependency injection in action.
      – David Arno
      yesterday










    • @DavidArno Yeah, you're right. I've adjusted the terminology.
      – jpmc26
      yesterday








    1




    1




    "Dependency injection is a technique that is intended to help you avoid huge, tangled construction trees...". Your first example after this claim is an example of pure, or poor man's, dependency injection. The second is an example of using an IoC container to "automate" the injection of those dependencies. Both are examples of dependency injection in action.
    – David Arno
    yesterday




    "Dependency injection is a technique that is intended to help you avoid huge, tangled construction trees...". Your first example after this claim is an example of pure, or poor man's, dependency injection. The second is an example of using an IoC container to "automate" the injection of those dependencies. Both are examples of dependency injection in action.
    – David Arno
    yesterday












    @DavidArno Yeah, you're right. I've adjusted the terminology.
    – jpmc26
    yesterday




    @DavidArno Yeah, you're right. I've adjusted the terminology.
    – jpmc26
    yesterday










    up vote
    0
    down vote













    As a customer, when you hire a mechanic to do something to your car, do you expect that mechanic to build a car from scratch only to then work with it? No, you give the mechanic the car you want them to work on.



    As the garage owner, when you instruct a mechanic to do something to a car, do you expect the mechanic to create his own screwdriver/wrench/car parts? No, you provide the mechanic with the parts/tools he needs to use



    Why do we do this? Well, think about it. You're a garage owner who wants to hire someone to become your mechanic. You will teach them to be a mechanic (= you will write the code).



    What's going to be easier:




    • Teach a mechanic how to attach a spoiler to a car using a screwdriver.

    • Teach a mechanic to create a car, create a spoiler, created a screwdriver
      and then attach the newly created spoiler to the newly created car with the newly created screwdriver.


    There are massive benefits to not having your mechanic create everything from scratch:




    • Obviously, training (= development) is dramatically shortened if you just supply your mechanic with existing tools and parts.

    • If the same mechanic has to perform the same job multiple times, you can make sure he reuses the screwdriver instead of always throwing the old one out and creating a new one.

    • Additionally, a mechanic who has learned to create everything will need to be much more of an expert, and thus will expect a higher wage. The coding analogy here is that a class with many responsibilities is much harder to maintain than a class with a single strictly defined responsibility.

    • Additionally, when new inventions hit the market and spoilers are now being made from carbon instead of plastic; you will have to retrain (= redevelop) your expert mechanic. But your "simple" mechanic won't have to be retrained as long as the spoiler can still be attached in the same way.

    • Having a mechanic who doesn't rely on a car that they've built themselves means that you have a mechanic who is able to handle any car they may receive. Including cars that didn't even exist yet at the time of training the mechanic. However, your expert mechanic will not be able to build newer cars that have been created after their training.


    If you hire and train the expert mechanic, you're going to end up with an employee who costs more, takes more time to perform what ought to be a simple job, and will perpetually need to be retrained whenever one of their many responsibilities need to be updated.



    The development analogy is that if you use classes with hardcoded dependencies, then you're going to end up with hard to maintain classes which will need continual redevelopment/changes whenever a new version of the object (Settings in your case) is created, and you'll have to develop internal logic for the class to have the ability to create different types of Settings objects.



    Furthermore, whoever consumes your class is now also going to have to ask the class to create the correct Settings object, as opposed to simply being able to pass the class any Settings object it wishes to pass. This means additional development for the consumer to figure out how to ask the class to create the right tool.





    Yes, dependency inversion takes a bit more effort to write instead of hardcoding the dependency. Yes, it's annoying to have to type more.



    But that is the same argument as choosing to hardcode literal values because "declaring variables takes more effort". Technically correct, but the pro's outweigh the cons by several orders of magnitude.



    The benefit of dependency inversion is not experienced when you create the first version of the application. The benefit of dependency inversion is experienced when you need to change or extend that initial version. And don't trick yourself into thinking that you will get it right the first time and won't need to extend/change the code. You will have to change things.






    does this affect performance as a whole?




    This does not affect runtime performance of the application. But it massively impacts the development time (and therefore performance) of the developer.






    share|improve this answer



















    • 2




      If you removed your comment, "As a minor comment, your question focuses on dependency inversion, not dependency injection. Injection is one way to do inversion, but it's not the only way.", this would be an excellent answer. Dependency inversion can be achieved via either injection or locator/globals. The question's examples relate to injection. So the question is about dependency injection (as well as dependency inversion).
      – David Arno
      yesterday










    • @DavidArno As I understand it, injection is the automated filling of method/constructor parameters as opposed to manually passing them. For the locator, does the locator itself then not become a dependency? It sounds like it's shifting the problem.
      – Flater
      yesterday






    • 11




      I think the whole car thing is a bit belaboured and confusing
      – Ewan
      yesterday






    • 3




      @Flater, part of the problem is no one really seems to agree on what the difference between dependency injection, dependency inversion and inversion of control are. One thing is for certain though, a "container" most certainly isn't needed to inject a dependency into a method or constructor. Pure (or poor man's) DI specifically describes manual dependency injection. It's the only dependency injection I personally use as I dislike the "magic" associated with containers.
      – David Arno
      yesterday






    • 1




      Your mechanic analogy is poor even as an analogy. If I have a mechanic trained how to fix cars, he can fix most varieties but if I come to him with a EV instead, he's likely to have no clue what to do with it. DI does not fix the polymorphic problem, all it does is help with coupling - ie how to get the car and mechanic together. A better analogy is a mechanic working for a dealer who only fixed 1 brand of car going independent and fixing other brands of car.
      – gbjbaanb
      5 hours ago















    up vote
    0
    down vote













    As a customer, when you hire a mechanic to do something to your car, do you expect that mechanic to build a car from scratch only to then work with it? No, you give the mechanic the car you want them to work on.



    As the garage owner, when you instruct a mechanic to do something to a car, do you expect the mechanic to create his own screwdriver/wrench/car parts? No, you provide the mechanic with the parts/tools he needs to use



    Why do we do this? Well, think about it. You're a garage owner who wants to hire someone to become your mechanic. You will teach them to be a mechanic (= you will write the code).



    What's going to be easier:




    • Teach a mechanic how to attach a spoiler to a car using a screwdriver.

    • Teach a mechanic to create a car, create a spoiler, created a screwdriver
      and then attach the newly created spoiler to the newly created car with the newly created screwdriver.


    There are massive benefits to not having your mechanic create everything from scratch:




    • Obviously, training (= development) is dramatically shortened if you just supply your mechanic with existing tools and parts.

    • If the same mechanic has to perform the same job multiple times, you can make sure he reuses the screwdriver instead of always throwing the old one out and creating a new one.

    • Additionally, a mechanic who has learned to create everything will need to be much more of an expert, and thus will expect a higher wage. The coding analogy here is that a class with many responsibilities is much harder to maintain than a class with a single strictly defined responsibility.

    • Additionally, when new inventions hit the market and spoilers are now being made from carbon instead of plastic; you will have to retrain (= redevelop) your expert mechanic. But your "simple" mechanic won't have to be retrained as long as the spoiler can still be attached in the same way.

    • Having a mechanic who doesn't rely on a car that they've built themselves means that you have a mechanic who is able to handle any car they may receive. Including cars that didn't even exist yet at the time of training the mechanic. However, your expert mechanic will not be able to build newer cars that have been created after their training.


    If you hire and train the expert mechanic, you're going to end up with an employee who costs more, takes more time to perform what ought to be a simple job, and will perpetually need to be retrained whenever one of their many responsibilities need to be updated.



    The development analogy is that if you use classes with hardcoded dependencies, then you're going to end up with hard to maintain classes which will need continual redevelopment/changes whenever a new version of the object (Settings in your case) is created, and you'll have to develop internal logic for the class to have the ability to create different types of Settings objects.



    Furthermore, whoever consumes your class is now also going to have to ask the class to create the correct Settings object, as opposed to simply being able to pass the class any Settings object it wishes to pass. This means additional development for the consumer to figure out how to ask the class to create the right tool.





    Yes, dependency inversion takes a bit more effort to write instead of hardcoding the dependency. Yes, it's annoying to have to type more.



    But that is the same argument as choosing to hardcode literal values because "declaring variables takes more effort". Technically correct, but the pro's outweigh the cons by several orders of magnitude.



    The benefit of dependency inversion is not experienced when you create the first version of the application. The benefit of dependency inversion is experienced when you need to change or extend that initial version. And don't trick yourself into thinking that you will get it right the first time and won't need to extend/change the code. You will have to change things.






    does this affect performance as a whole?




    This does not affect runtime performance of the application. But it massively impacts the development time (and therefore performance) of the developer.






    share|improve this answer



















    • 2




      If you removed your comment, "As a minor comment, your question focuses on dependency inversion, not dependency injection. Injection is one way to do inversion, but it's not the only way.", this would be an excellent answer. Dependency inversion can be achieved via either injection or locator/globals. The question's examples relate to injection. So the question is about dependency injection (as well as dependency inversion).
      – David Arno
      yesterday










    • @DavidArno As I understand it, injection is the automated filling of method/constructor parameters as opposed to manually passing them. For the locator, does the locator itself then not become a dependency? It sounds like it's shifting the problem.
      – Flater
      yesterday






    • 11




      I think the whole car thing is a bit belaboured and confusing
      – Ewan
      yesterday






    • 3




      @Flater, part of the problem is no one really seems to agree on what the difference between dependency injection, dependency inversion and inversion of control are. One thing is for certain though, a "container" most certainly isn't needed to inject a dependency into a method or constructor. Pure (or poor man's) DI specifically describes manual dependency injection. It's the only dependency injection I personally use as I dislike the "magic" associated with containers.
      – David Arno
      yesterday






    • 1




      Your mechanic analogy is poor even as an analogy. If I have a mechanic trained how to fix cars, he can fix most varieties but if I come to him with a EV instead, he's likely to have no clue what to do with it. DI does not fix the polymorphic problem, all it does is help with coupling - ie how to get the car and mechanic together. A better analogy is a mechanic working for a dealer who only fixed 1 brand of car going independent and fixing other brands of car.
      – gbjbaanb
      5 hours ago













    up vote
    0
    down vote










    up vote
    0
    down vote









    As a customer, when you hire a mechanic to do something to your car, do you expect that mechanic to build a car from scratch only to then work with it? No, you give the mechanic the car you want them to work on.



    As the garage owner, when you instruct a mechanic to do something to a car, do you expect the mechanic to create his own screwdriver/wrench/car parts? No, you provide the mechanic with the parts/tools he needs to use



    Why do we do this? Well, think about it. You're a garage owner who wants to hire someone to become your mechanic. You will teach them to be a mechanic (= you will write the code).



    What's going to be easier:




    • Teach a mechanic how to attach a spoiler to a car using a screwdriver.

    • Teach a mechanic to create a car, create a spoiler, created a screwdriver
      and then attach the newly created spoiler to the newly created car with the newly created screwdriver.


    There are massive benefits to not having your mechanic create everything from scratch:




    • Obviously, training (= development) is dramatically shortened if you just supply your mechanic with existing tools and parts.

    • If the same mechanic has to perform the same job multiple times, you can make sure he reuses the screwdriver instead of always throwing the old one out and creating a new one.

    • Additionally, a mechanic who has learned to create everything will need to be much more of an expert, and thus will expect a higher wage. The coding analogy here is that a class with many responsibilities is much harder to maintain than a class with a single strictly defined responsibility.

    • Additionally, when new inventions hit the market and spoilers are now being made from carbon instead of plastic; you will have to retrain (= redevelop) your expert mechanic. But your "simple" mechanic won't have to be retrained as long as the spoiler can still be attached in the same way.

    • Having a mechanic who doesn't rely on a car that they've built themselves means that you have a mechanic who is able to handle any car they may receive. Including cars that didn't even exist yet at the time of training the mechanic. However, your expert mechanic will not be able to build newer cars that have been created after their training.


    If you hire and train the expert mechanic, you're going to end up with an employee who costs more, takes more time to perform what ought to be a simple job, and will perpetually need to be retrained whenever one of their many responsibilities need to be updated.



    The development analogy is that if you use classes with hardcoded dependencies, then you're going to end up with hard to maintain classes which will need continual redevelopment/changes whenever a new version of the object (Settings in your case) is created, and you'll have to develop internal logic for the class to have the ability to create different types of Settings objects.



    Furthermore, whoever consumes your class is now also going to have to ask the class to create the correct Settings object, as opposed to simply being able to pass the class any Settings object it wishes to pass. This means additional development for the consumer to figure out how to ask the class to create the right tool.





    Yes, dependency inversion takes a bit more effort to write instead of hardcoding the dependency. Yes, it's annoying to have to type more.



    But that is the same argument as choosing to hardcode literal values because "declaring variables takes more effort". Technically correct, but the pro's outweigh the cons by several orders of magnitude.



    The benefit of dependency inversion is not experienced when you create the first version of the application. The benefit of dependency inversion is experienced when you need to change or extend that initial version. And don't trick yourself into thinking that you will get it right the first time and won't need to extend/change the code. You will have to change things.






    does this affect performance as a whole?




    This does not affect runtime performance of the application. But it massively impacts the development time (and therefore performance) of the developer.






    share|improve this answer














    As a customer, when you hire a mechanic to do something to your car, do you expect that mechanic to build a car from scratch only to then work with it? No, you give the mechanic the car you want them to work on.



    As the garage owner, when you instruct a mechanic to do something to a car, do you expect the mechanic to create his own screwdriver/wrench/car parts? No, you provide the mechanic with the parts/tools he needs to use



    Why do we do this? Well, think about it. You're a garage owner who wants to hire someone to become your mechanic. You will teach them to be a mechanic (= you will write the code).



    What's going to be easier:




    • Teach a mechanic how to attach a spoiler to a car using a screwdriver.

    • Teach a mechanic to create a car, create a spoiler, created a screwdriver
      and then attach the newly created spoiler to the newly created car with the newly created screwdriver.


    There are massive benefits to not having your mechanic create everything from scratch:




    • Obviously, training (= development) is dramatically shortened if you just supply your mechanic with existing tools and parts.

    • If the same mechanic has to perform the same job multiple times, you can make sure he reuses the screwdriver instead of always throwing the old one out and creating a new one.

    • Additionally, a mechanic who has learned to create everything will need to be much more of an expert, and thus will expect a higher wage. The coding analogy here is that a class with many responsibilities is much harder to maintain than a class with a single strictly defined responsibility.

    • Additionally, when new inventions hit the market and spoilers are now being made from carbon instead of plastic; you will have to retrain (= redevelop) your expert mechanic. But your "simple" mechanic won't have to be retrained as long as the spoiler can still be attached in the same way.

    • Having a mechanic who doesn't rely on a car that they've built themselves means that you have a mechanic who is able to handle any car they may receive. Including cars that didn't even exist yet at the time of training the mechanic. However, your expert mechanic will not be able to build newer cars that have been created after their training.


    If you hire and train the expert mechanic, you're going to end up with an employee who costs more, takes more time to perform what ought to be a simple job, and will perpetually need to be retrained whenever one of their many responsibilities need to be updated.



    The development analogy is that if you use classes with hardcoded dependencies, then you're going to end up with hard to maintain classes which will need continual redevelopment/changes whenever a new version of the object (Settings in your case) is created, and you'll have to develop internal logic for the class to have the ability to create different types of Settings objects.



    Furthermore, whoever consumes your class is now also going to have to ask the class to create the correct Settings object, as opposed to simply being able to pass the class any Settings object it wishes to pass. This means additional development for the consumer to figure out how to ask the class to create the right tool.





    Yes, dependency inversion takes a bit more effort to write instead of hardcoding the dependency. Yes, it's annoying to have to type more.



    But that is the same argument as choosing to hardcode literal values because "declaring variables takes more effort". Technically correct, but the pro's outweigh the cons by several orders of magnitude.



    The benefit of dependency inversion is not experienced when you create the first version of the application. The benefit of dependency inversion is experienced when you need to change or extend that initial version. And don't trick yourself into thinking that you will get it right the first time and won't need to extend/change the code. You will have to change things.






    does this affect performance as a whole?




    This does not affect runtime performance of the application. But it massively impacts the development time (and therefore performance) of the developer.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 13 hours ago

























    answered yesterday









    Flater

    5,26511019




    5,26511019








    • 2




      If you removed your comment, "As a minor comment, your question focuses on dependency inversion, not dependency injection. Injection is one way to do inversion, but it's not the only way.", this would be an excellent answer. Dependency inversion can be achieved via either injection or locator/globals. The question's examples relate to injection. So the question is about dependency injection (as well as dependency inversion).
      – David Arno
      yesterday










    • @DavidArno As I understand it, injection is the automated filling of method/constructor parameters as opposed to manually passing them. For the locator, does the locator itself then not become a dependency? It sounds like it's shifting the problem.
      – Flater
      yesterday






    • 11




      I think the whole car thing is a bit belaboured and confusing
      – Ewan
      yesterday






    • 3




      @Flater, part of the problem is no one really seems to agree on what the difference between dependency injection, dependency inversion and inversion of control are. One thing is for certain though, a "container" most certainly isn't needed to inject a dependency into a method or constructor. Pure (or poor man's) DI specifically describes manual dependency injection. It's the only dependency injection I personally use as I dislike the "magic" associated with containers.
      – David Arno
      yesterday






    • 1




      Your mechanic analogy is poor even as an analogy. If I have a mechanic trained how to fix cars, he can fix most varieties but if I come to him with a EV instead, he's likely to have no clue what to do with it. DI does not fix the polymorphic problem, all it does is help with coupling - ie how to get the car and mechanic together. A better analogy is a mechanic working for a dealer who only fixed 1 brand of car going independent and fixing other brands of car.
      – gbjbaanb
      5 hours ago














    • 2




      If you removed your comment, "As a minor comment, your question focuses on dependency inversion, not dependency injection. Injection is one way to do inversion, but it's not the only way.", this would be an excellent answer. Dependency inversion can be achieved via either injection or locator/globals. The question's examples relate to injection. So the question is about dependency injection (as well as dependency inversion).
      – David Arno
      yesterday










    • @DavidArno As I understand it, injection is the automated filling of method/constructor parameters as opposed to manually passing them. For the locator, does the locator itself then not become a dependency? It sounds like it's shifting the problem.
      – Flater
      yesterday






    • 11




      I think the whole car thing is a bit belaboured and confusing
      – Ewan
      yesterday






    • 3




      @Flater, part of the problem is no one really seems to agree on what the difference between dependency injection, dependency inversion and inversion of control are. One thing is for certain though, a "container" most certainly isn't needed to inject a dependency into a method or constructor. Pure (or poor man's) DI specifically describes manual dependency injection. It's the only dependency injection I personally use as I dislike the "magic" associated with containers.
      – David Arno
      yesterday






    • 1




      Your mechanic analogy is poor even as an analogy. If I have a mechanic trained how to fix cars, he can fix most varieties but if I come to him with a EV instead, he's likely to have no clue what to do with it. DI does not fix the polymorphic problem, all it does is help with coupling - ie how to get the car and mechanic together. A better analogy is a mechanic working for a dealer who only fixed 1 brand of car going independent and fixing other brands of car.
      – gbjbaanb
      5 hours ago








    2




    2




    If you removed your comment, "As a minor comment, your question focuses on dependency inversion, not dependency injection. Injection is one way to do inversion, but it's not the only way.", this would be an excellent answer. Dependency inversion can be achieved via either injection or locator/globals. The question's examples relate to injection. So the question is about dependency injection (as well as dependency inversion).
    – David Arno
    yesterday




    If you removed your comment, "As a minor comment, your question focuses on dependency inversion, not dependency injection. Injection is one way to do inversion, but it's not the only way.", this would be an excellent answer. Dependency inversion can be achieved via either injection or locator/globals. The question's examples relate to injection. So the question is about dependency injection (as well as dependency inversion).
    – David Arno
    yesterday












    @DavidArno As I understand it, injection is the automated filling of method/constructor parameters as opposed to manually passing them. For the locator, does the locator itself then not become a dependency? It sounds like it's shifting the problem.
    – Flater
    yesterday




    @DavidArno As I understand it, injection is the automated filling of method/constructor parameters as opposed to manually passing them. For the locator, does the locator itself then not become a dependency? It sounds like it's shifting the problem.
    – Flater
    yesterday




    11




    11




    I think the whole car thing is a bit belaboured and confusing
    – Ewan
    yesterday




    I think the whole car thing is a bit belaboured and confusing
    – Ewan
    yesterday




    3




    3




    @Flater, part of the problem is no one really seems to agree on what the difference between dependency injection, dependency inversion and inversion of control are. One thing is for certain though, a "container" most certainly isn't needed to inject a dependency into a method or constructor. Pure (or poor man's) DI specifically describes manual dependency injection. It's the only dependency injection I personally use as I dislike the "magic" associated with containers.
    – David Arno
    yesterday




    @Flater, part of the problem is no one really seems to agree on what the difference between dependency injection, dependency inversion and inversion of control are. One thing is for certain though, a "container" most certainly isn't needed to inject a dependency into a method or constructor. Pure (or poor man's) DI specifically describes manual dependency injection. It's the only dependency injection I personally use as I dislike the "magic" associated with containers.
    – David Arno
    yesterday




    1




    1




    Your mechanic analogy is poor even as an analogy. If I have a mechanic trained how to fix cars, he can fix most varieties but if I come to him with a EV instead, he's likely to have no clue what to do with it. DI does not fix the polymorphic problem, all it does is help with coupling - ie how to get the car and mechanic together. A better analogy is a mechanic working for a dealer who only fixed 1 brand of car going independent and fixing other brands of car.
    – gbjbaanb
    5 hours ago




    Your mechanic analogy is poor even as an analogy. If I have a mechanic trained how to fix cars, he can fix most varieties but if I come to him with a EV instead, he's likely to have no clue what to do with it. DI does not fix the polymorphic problem, all it does is help with coupling - ie how to get the car and mechanic together. A better analogy is a mechanic working for a dealer who only fixed 1 brand of car going independent and fixing other brands of car.
    – gbjbaanb
    5 hours ago










    up vote
    0
    down vote













    I was always baffled by dependency injection. It seemed to only exist within Java spheres, but those spheres spoke of it with great reverence. It was one of the great Patterns, you see, which are said to bring order to chaos. But the examples were always convoluted and artificial, establishing a non-problem and then setting out to solve it by making the code more complicated.



    It made more sense when a fellow Python dev imparted to me this wisdom: it's just passing arguments to functions. It's barely a pattern at all; more like a reminder that you can ask for something as an argument, even if you could have conceivably provided a reasonable value yourself.



    So your question is roughly equivalent to "why should my function take arguments?" and has many of the same answers, namely: to let the caller make decisions.



    This comes with a cost, of course, because now you're forcing the caller to make some decision (unless you make the argument optional), and the interface is somewhat more complex. In exchange, you gain flexibility.



    So: Is there a good reason you specifically need to use this particular Setting type/value? Is there a good reason calling code might want a different Setting type/value? (Remember, tests are code!)






    share|improve this answer








    New contributor




    Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      0
      down vote













      I was always baffled by dependency injection. It seemed to only exist within Java spheres, but those spheres spoke of it with great reverence. It was one of the great Patterns, you see, which are said to bring order to chaos. But the examples were always convoluted and artificial, establishing a non-problem and then setting out to solve it by making the code more complicated.



      It made more sense when a fellow Python dev imparted to me this wisdom: it's just passing arguments to functions. It's barely a pattern at all; more like a reminder that you can ask for something as an argument, even if you could have conceivably provided a reasonable value yourself.



      So your question is roughly equivalent to "why should my function take arguments?" and has many of the same answers, namely: to let the caller make decisions.



      This comes with a cost, of course, because now you're forcing the caller to make some decision (unless you make the argument optional), and the interface is somewhat more complex. In exchange, you gain flexibility.



      So: Is there a good reason you specifically need to use this particular Setting type/value? Is there a good reason calling code might want a different Setting type/value? (Remember, tests are code!)






      share|improve this answer








      New contributor




      Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















        up vote
        0
        down vote










        up vote
        0
        down vote









        I was always baffled by dependency injection. It seemed to only exist within Java spheres, but those spheres spoke of it with great reverence. It was one of the great Patterns, you see, which are said to bring order to chaos. But the examples were always convoluted and artificial, establishing a non-problem and then setting out to solve it by making the code more complicated.



        It made more sense when a fellow Python dev imparted to me this wisdom: it's just passing arguments to functions. It's barely a pattern at all; more like a reminder that you can ask for something as an argument, even if you could have conceivably provided a reasonable value yourself.



        So your question is roughly equivalent to "why should my function take arguments?" and has many of the same answers, namely: to let the caller make decisions.



        This comes with a cost, of course, because now you're forcing the caller to make some decision (unless you make the argument optional), and the interface is somewhat more complex. In exchange, you gain flexibility.



        So: Is there a good reason you specifically need to use this particular Setting type/value? Is there a good reason calling code might want a different Setting type/value? (Remember, tests are code!)






        share|improve this answer








        New contributor




        Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        I was always baffled by dependency injection. It seemed to only exist within Java spheres, but those spheres spoke of it with great reverence. It was one of the great Patterns, you see, which are said to bring order to chaos. But the examples were always convoluted and artificial, establishing a non-problem and then setting out to solve it by making the code more complicated.



        It made more sense when a fellow Python dev imparted to me this wisdom: it's just passing arguments to functions. It's barely a pattern at all; more like a reminder that you can ask for something as an argument, even if you could have conceivably provided a reasonable value yourself.



        So your question is roughly equivalent to "why should my function take arguments?" and has many of the same answers, namely: to let the caller make decisions.



        This comes with a cost, of course, because now you're forcing the caller to make some decision (unless you make the argument optional), and the interface is somewhat more complex. In exchange, you gain flexibility.



        So: Is there a good reason you specifically need to use this particular Setting type/value? Is there a good reason calling code might want a different Setting type/value? (Remember, tests are code!)







        share|improve this answer








        New contributor




        Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        share|improve this answer



        share|improve this answer






        New contributor




        Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        answered 4 hours ago









        Eevee

        1097




        1097




        New contributor




        Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





        New contributor





        Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






        Eevee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.

















            protected by gnat 33 mins ago



            Thank you for your interest in this question.
            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



            Would you like to answer one of these unanswered questions instead?



            Popular posts from this blog

            Plaza Victoria

            Puebla de Zaragoza

            Musa