What is the difference between polymorphism and dependency injection in PHP?
To me they seem like the same thing.
Polymorphism is the provision of a single interface to entities of different types. This means that you define one parent class, i.e. Person and derive multiple other classes off of it. I.E. Mailman, Programmer, Dentist. These child classes all have something in common with person, but they implement specialized functions as well.
Dependency Injection is a software design pattern that implements inversion of control and allows a program design to follow the dependency inversion principle. The term was coined by Martin Fowler. An injection is the passing of a dependency (a service) to a dependent object (a client). A database is a good example of this. Let's say our person class above needs to persist some data about itself. Dependency injection would involve passing a database object into the Person class to work with. The Person class doesn't worry about how the database persists its information, it is only concerned with the public api of the database. You could effectively swap out databases and as long as their apis are the same, the Person class would not care. This becomes very handy when you want to unit test your classes and need to remove the dependency on the database. You can use dependency injection to pass in a mock database that always returns dummy information.
Here are two previous stackoverflow questions related to each:
What is polymorphism, what is it for, and how is it used?
What is dependency injection?
Also, check out Martin Fowler's site for more information of this.
http://www.martinfowler.com/articles/injection.html
I think dependency injection is much simpler. Its like to inject a class(object) and call a parent method. Similar to a wrapper. Polymorphism uses abstract classes and it let you define non-existance functions.
How I understand it now:
polymorphism + injected object = dependency injection
Polymorphism - is when you create objects that implement the same interface, so all objects have the same base methods.
Dependency injection - you inject object, that can be swapped with other object. But all those object implement the same interface (like in polymorphism).
Related
Two design patterns namely Dependency Injection and Dependency Inversion exist out there, Articles are there in the net trying to explain the difference. But the need to explain it in easier words is still there. Any one out there to come up to ?
I need to understand it in PHP.
(Note: This answer is language-agnostic, although the question specifically mentions PHP, but being unfamiliar with PHP, I have not provided any PHP examples).
Terminology - Dependencies and Coupling
In the context of Object-Oriented Programming, a dependency is any other object type which a class has a direct relationship with. When a class depends directly upon another object type, it can be described as being coupled to that type.
In general, any type used by a class is a dependency to some extent. There are many different ways for a class to depend upon another type, including:
Object types used by Instance variables
Object types used by Constructor parameters
Object types used by Accessor/Mutator methods
Constructors (And sometimes methods) which create new objects directly
Inheritance
The stronger the relationship between a class and its dependency, the tighter the coupling; therefore when a class depends directly upon another concrete class (such as the case with inheritance creating a direct dependency on a base class, or the case where a constructor creates new objects for its instance variables), any future changes to that direct dependency are more likely to "ripple" across in a Butterfly-effect style.
Difference Between Injection vs Inversion
Dependency Injection is an Inversion of Control technique for supplying objects ('dependencies') to a class by way of the Dependency Injection Design Pattern. Typically passing dependencies via one of the following:
A constructor
A public property or field
A public setter
The Dependency Inversion Principle (DIP) is a software design guideline which boils down to two recommendations about de-coupling a class from its concrete dependencies:
'High-level modules should not depend on low-level modules. Both should depend on abstractions.'
'Abstractions should not depend upon details. Details should depend upon abstractions.'
Or, to put it even more succinctly:
Dependency Injection is an implementation technique for populating instance variables of a class.
Dependency Inversion is a general design guideline which recommends that classes should only have direct relationships with high-level abstractions.
Dependency Injection and Inversion of Control (IoC)
Dependency Injection applies the IoC principle by ensuring classes are never responsible for creating or supplying their own dependencies (and therefore aren't responsible for the lifetime of those dependencies either).
However, IoC is not Dependency Injection - indeed, IoC as a principle has nothing particularly to do with dependencies or dependency injection per-se; Dependency Injection is a design pattern based around the principle of IoC.
IoC is seen in many other contexts, including those totally unrelated to object creation or dependencies, such as message passing via a Mediator or Message pump to trigger event handlers. Other (unrelated) examples of IoC include:
A windowed application using event handler functions/methods to handle mouse/keyboard input events.
An MVC web application using Controller Actions to handle HTTP requests.
(Updated from the original answer as a separate explanation about IoC)
Dependency Injection Pattern
Dependency Injection is a design pattern which applies the IoC principle to ensure that a class has absolutely no involvement or awareness in the creation or lifetime of objects used by its constructor or instance variables -- the "common" concern about object creation and populating instance variables is deferred to a framework instead.
That is to say, a class may specify its instance variables, but does not do any work to populate those instance variables (with the exception of using constructor parameters as a "pass-through")
A class which is designed with Dependency Injection in mind may look like this:
// Dependency Injection Example...
class Foo {
// Constructor uses DI to obtain the Meow and Woof dependencies
constructor(fred: Meow, barney: Woof) {
this.fred = fred;
this.barney = barney;
}
}
In this example, Meow and Woof are both dependencies injected via the Foo constructor.
On the other hand, a Foo class which is designed without Dependency Injection might simply create the Meow and Woof instances itself, or perhaps use some kind of service locator/factory:
// Example without Dependency Injection...
class Foo {
constructor() {
// a 'Meow' instance is created within the Foo constructor
this.fred = new Meow();
// a service locator gets a 'WoofFactory' which in-turn
// is responsible for creating a 'Woof' instance.
// This demonstrates IoC but not Dependency Injection.
var factory = TheServiceLocator.GetWoofFactory();
this.barney = factory.CreateWoof();
}
}
So dependency injection simply means that a class has deferred responsibility of obtaining or providing its own dependencies; instead that responsibility resides with whatever wants to create an instance. (Which is usually an IoC Container)
Dependency Inversion Principle (DIP)
Dependency Inversion is broadly about de-coupling concrete classes by preventing those classes having any direct reference to each other.
The DIP is primarily concerned with ensuring that a class only depends upon higher-level abstractions. For example, interfaces exist at a higher level of abstraction than a concrete class.
The DIP is not about injecting dependencies, although the dependency injection pattern is one of many techniques which can help provide the level of indirection needed to avoid depending on low-level details and coupling with other concrete classes.
Note: Dependency Inversion is often more explicit in statically typed programming languages such as C# or Java, because those languages enforce strict type-checking on variable names. On the other hand, Dependency Inversion is already passively available in dynamic languages such as Python or JavaScript because variables in those languages do not have any particular type restrictions.
Consider a scenario in a statically typed language where a class requires the ability to read a record from the application's database:
// class Foo depends upon a concrete class called SqlRecordReader.
class Foo {
reader: SqlRecordReader;
constructor(sqlReader: SqlRecordReader) {
this.reader = sqlReader;
}
doSomething() {
var records = this.reader.readAll();
// etc.
}
}
In the above example, and despite the use of Dependency Injection, class Foo still has a hard dependency on SqlRecordReader, yet the only thing it really cares about is that there exists a method called readAll() which returns some records.
Consider the situation where SQL database queries are later refactored out into separate micro-services requiring a change to the codebase; the Foo class would need to read records from a remote service instead. Or alternatively, a situation where Foo unit tests need to read data from an in-memory store or a flat file.
If, as its name suggests, the SqlRecordReader contains database and SQL logic, any move to microservices would need the Foo class to change.
Dependency Inversion guidelines suggest that SqlRecordReader should be replaced with a higher-level abstraction which only provides the readAll() method. i.e:
interface IRecordReader {
Records[] getAll();
}
class Foo {
reader: IRecordReader;
constructor(reader: IRecordReader) {
this.reader = reader;
}
}
As per DIP, the IRecordReader is a higher-level abstraction than SqlRecordReader, and forcing Footo depend onIRecordReaderinstead ofSqlRecordReader` satisfies DIP guidelines.
Why DIP Guidelines are Useful
The keyword is guideline - dependency inversion adds indirection to the design of your program. The obvious disadvantage of adding any kind of indirection is that the complexity (i.e. the cognitive "load" required for a human to understand what's going on) increases.
In many cases, indirection can make code easier to maintain (fix bugs, add enhancements) however:
In this last example, Foo might receive a SqlRecordReader, or maybe a SoapRecordReader, or perhaps a FileRecordReader, or maybe even for unit testing a MockRecordReader - the point is that it doesn't know or care anything about different possible implementations of IRecordReader - provided of course those implementations live up to the Liskov Substitution Principle.
Furthermore, it avoids the potentially dirty scenario where a developer who is in a rush to get something working might consider trying to "fudge" the Liskov principle by inheriting the SoapRecordReader or FileRecordReader from a base class SqlRecordReader.
Worse still, an inexperienced developer might even change the SqlRecordReader itself so that class has logic not only for SQL but also for SOAP endpoints, The Filesystem, and anything else which might be needed. (This kind of thing happens too often in the real world - especially in poorly maintained code, and is nearly always a Code Smell.)
See this article here
The author differentiates these two in simple words. Dependency Injection == “Gimme it” and Dependency Inversion == “Someone take care of this for me, somehow.”. In dependency inversion principle, high level module is the owner of the abstraction. Thus the detail(implementation of the abstraction) is depends on the abstraction and hence depends on the high level module. Dependency inverted!.. Dependency injection is different. The abstraction might not be kept by the high level module. Thus an abstraction given to the higher level object might not be limited to the needs of the high level module.
Dependency inversion :
You have a higher level module X and an abstraction Y which is defined by X. Z implements Y and is given to X. Thus Z is dependent of X(via the abstraction Y defined by X).
Dependency injection:
You have an higher level module X which needs functionalities A and B. Y is an abstraction which contains the functionalities A, B and C. Z implements Y. Since Z implements Y and hence have functionalities A and B, Z is given to X. Now X is dependent of Y.
Dependancy injection is ability of object to supply depndcies of other object. in simple words it means something else is dependent on something else. Example Class A uses few functions of Class B now Class A needs to create the instance of Class B here the use of DI comes in to use.
IOC is to invert the different resposibilities for example you need to work at home but you need to cook to eat now listed cooking at home you can order it online and it is available to your door step which means you can focus on your work. Here you inverted cooking responsibilities to online restorent.
The Dependency Inversion Principle (DIP) states that high level modules should not depend on low level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.
Dependency Injection is one way to achieve Inversion of Control (which I am assuming you are referring to as Dependency Inversion), so the two aren’t really in competition as much as DI is a specialization of IoC. Other commonly seen ways to achieve IoC include using factories or the Service Locator pattern.
Is there a reasonable way to ensure that you aren't unnecessarily re-instantiating expensive object instances in PHP?
I have an application that deal with US States. Each state is an instance of the USState class. I'd like to ensure that the application only ever has one instance of each state object, although they are used in many places throughout the application.
I looked into the singleton pattern, but that seems to be used for times when a class only has a single instance - here there are 50 instances, but no more.
I guess I could put them in the global scope and always refer to them that way (global $california), but that seems wrong.
I would use Service Locator Pattern or Dependency Injection, which is provided by your framework. Usually I go with Zend Framework, but not knowing your circumstances, I assume you have no framework at all. In this case I would suggest very simple Dependency Injection Container, but that would add a dependency on DIC itself. Pimple is one of them.
I have recently studied dependency injection design pattern .
class User
{
private $db;
public function __construct(Database $db)
{
$this->$db = $db;
}
}
I can not help but wonder that is the same thing that i learned in aggregation. Please do correct me if I am wrong . I know goals of dependency injection and aggregation are different . Is there anything that I am missing ?
Aggregation is a form of object composition. It has nothing to do with dependency injection.
In the other hand, dependency injection isn't about how objects are associated with but how to get other objects (dependencies) into a particular object. Dependencies could be aggregates, services, repositories, validators, literals...
Usually, in strongly-typed languages, dependencies are introduced as interfaces to avoid coupling your objects to implementation details. In the opposite side, in dynamically-typed languages, conventions and a strong documentation do the trick to build up a good and tightly-coupled dependency graph.
Note that a database couldn't be an aggregate. Not all associations are considered to be aggregation, while you could consider an injected dependency.
Anyway, there's some design smell in your reasoning: an user shouldn't depend on a database, but a data layer / data mapping layer would be a better candidate to be injected into your user entity if you're going to implement something like active record pattern.
I can not help but wonder that is the same thing that i learned in aggregation
Consider a Department class for example that has an array of Professor objects as an instance variable. There are two ways in which you can initialize the professor array with some Professor objects.
You could initialize the elements of the Professor array within the Department class in some method that takes no parameters by saying professors[0]=new Professor("CK"); and professors[1]=new Professor("MK");.
You could provide a constructor that takes an array of Professor type as its argument. Any class that wants to instantiate a Department would then have to also pass an array of Professor objects to the constructor.
Aggregation : It doesn't matter whether you use option 1 or 2 to define how a Department gets its professors. A professor will continue to exist even if there is no department (assuming the professor belongs to more than one department) and this is therefore said to be aggregation regardless of how the department gets its professors.
Dependency Injection If you use option 2 to create a Department instance, this will be termed as dependency injection. A department needs professors and you are fulfilling this dependency by providing it from outside the Department class.
In other words, Aggregation is a type of relationship that can be modeled either using option 1 or option 2 (or other options such as getting the professors from a database and filling the Professor array in Department inside a method). Dependency injection is way of designing your class so that its dependencies can be provided from outside the class. An aggregate relationship can be modeled to support dependency injection but that does not mean Aggregation and Dependency Injection are the same thing.
Aggregation is generally modeled as a one-to-many relationship, and furthermore, tends to imply part-whole semantics. For these reasons, a DB of Users would generally not be considered aggregation: the relationship is 1:1 and the concept of a User does not necessarily imply a DB.
Contrast this with the common aggregation example of a car and its wheels. There is a one-to-many relationship, and the concept of a Car usually implies that it has wheels.
Dependency Injection may be thought of as the way in which a relationship is created. The relationship may be 1:1 or one-to-many. It may imply certain semantics, or not. The critical feature of DI is that User does not control the creation of DB, nor initiate its creation.
In practice, aggregation relationships may often be created via dependency injection; but that does not imply the two concepts are equivalent. DI can create other kinds of relationships, and aggregation may be created without DI.
Aggregation is a way of maintaining associations between objects. You use this term when describing how you structure relations between objects. It is a domain term, the same kind of relation exists between objects in real life.
Dependency injection is a way to manage dependencies between objects in order to achieve loose coupling. The same techniques can be used in aggregates. But usually, in aggregates, it is not about coupling but about how your objects are related. This term also has analogies from real life but they are used mostly to explain what is the inversion of control, usually, there is no correspondence to your domain.
I decided to add these points.
If I think from your point of view you should be asking this question because Aggregation & Dependency Injection promotes an entity which can be put into some other entities and also can work alone.
But there is a difference. In Aggregation you are working with direct objects. i.e. objects which maintains a state, life-cycle etc.
Ex:
Bulb & Room
Instances of Bulb can be put into instances of Room.
But not only Room, some instances can be put into instances of Car, Radio etc.
And also instances of Bulb can work independently without being put into the instances of other objects too.
But in Dependency Injection we focus on class level interactions. This is somewhat diverged with pure OOP practice. Actually in DI we tend to inject stateless classes (worker classes) into some other classes. Though they look like objects they are actually just stateless classes that are being injected. And instances of that class can stand independently too. DI is widely used as an alternative for Traditional Singleton Pattern because that traditional way has some negative side-effects.
Ex:
Assume a stateless worker class called StringUtils (not the apache one which is stacked with static methods.). It can be injected into classes called NounUtils, VerbUtils etc. And also instances of StringUtils can also exist.
Hope you got an idea. :))
When I first saw dependency injection components like PHP-DI, Symfony2 DI, etc., I though, there is a way to automatically inject instance of any class to any just with one instantiation.
So
1. Create instance in root class like $foo = new Foo()
2. And then I can use this instance in any object (like global singleton) without passing reference to constructor or method of the class I want to call from.
But I found out, that basicly I can use Dependency Injection in 2 ways
1. Passing the reference of the instance to constructor
2. Creating container where all objects are located. This container could be injected to other classes, but "This is not recommended".
As both ways can be easily done in pure PHP, the first is clear, the second could be solved with static properties, so why to use PHP-DI or Symfony2 for this work?
Why should you use Dependency Injection over the Singleton pattern?
Let's assume we have a Singleton object named DatabaseConnection which wraps a connection to a MySQL database for us and does some other neat things, who knows. Because reusing code is a good thing, we use this object in a lot of projects.
What if at some point we decide to switch one of our projects from MySQL to another database product? We would have to modify every place where we call the DatabaseConnection object and replace it with our new implementation. Or, we could modify the class itself -- but we still want to use the original one with other projects, so we end up with two implementations with the same name which is just asking for trouble, really.
And what about unit tests? We do those, of course, because we are good developers! But if we unit test a function that uses the database, we don't want the test to actually rely on the database or even change things there. There's no way to replace the DatabaseConnection with a mock object (that just returns static data) because our project is tightly coupled to it.
That's what Dependency Injection does: It helps to prevent tight coupling. If we inject the connection with $someObject->setDatabaseConnection($databaseConnection), we can inject any object there that behaves like the original one. We can inject mock objects, alternative implementations or extensions that inherit the original class.
Now a Dependency Injection Container is just a nice helper to manage object instances and their dependencies more easily, but it's not needed for doing Dependency Injection.
So I'm making this web application in PHP, and I wanted to make a decent model layer (as much as possible) with Domain Objects and Data Mappers, all orchestrated by Services.
And now I'm thinking, how should I create my objects?
Factories?
But then:
I'd have to use reflection to actually enforce if an object implements a certain interface (DataMapper usually. The others don't have set methods they need to implement; I don't want to rely on names, because naming conventions change).
I'd have to defy the law of demeter by passing the factories into the ServiceFactory which would then only pass it to the service it creates.
The new keyword?
But then:
I'd have problems testing the code in isolation.
Feels too tightly coupled.
Anything else?
I don't know, that's why I'm asking! :P
What should I do? Is there a better approach to this?
Brian Vanderbusch's comment hints at the best way. You should use Dependency Injection to inject the mapper you need. However, to reduce coupling you should also type hint the most basic type, usually an interface.
How you actually inject the Data Mapper into your (presumably) model layer doesn't really matter. A Dependency Injection Container can store all the metadata about which classes need which data mappers and automatically inject the dependencies for you. However, without using a DIC, the top level of your code should, at the most basic level, look like this:
$model = new ProductsModel(new ProductsDataMapper(new Db('localhost', 'u', 'p', 'd')));
of course the mapper and database would almost certainly be shared between other objects in the real world and you'd pass in the references to the existing instances. If you need multiple mappers in the model layer, pass them all in as constructor arguments.
The key here is to build the entire object graph at the very top level of the application rather than worrying about locating them after the fact. This is the premise of inversion of control, which you can think of as building the structure from inside out.