I have been searching for an answer in this topic but I haven’t been able to find a satisfactory one like in other topics, where the consensus is solid.
The situation
To keep things simple: I am implementing a custom Dependency Injection Container into one of my current projects (I know, I should use an already built one, but I’m doing it with learning purposes; so answers like ‘use this func of that container…’ are not useful) and I’ve stumbled a problem with instantiation of new elements inside a collection.
The problem
Imagine that I have a complex object, for example a car. This car has several dependencies (engine, axis, seats, airbags…) that have, at the same time, their own dependencies, and so on.
It is not a big issue to make the DiC (via autowiring or using a config file) build the object graph and inject all the dependencies with a simple line of code like:
$car = $container->get(‘car’);
The problem arrives when I build a CarCollection, which is a simple class that wraps an array of cars. The issue comes when I try to use a method that populates the collection with all the cars that exist in the database. It’s obvios that the collection should be able to create the Car objects on the fly when we call the “getAll” method from the database.
The code would be something like this:
public function populate(array $filters) {
$all_data = $this->dao->getAll($filters); // Call the data access object to query all cars.
foreach($all_data as $data) {
$new_object = $this->container(‘car’); // create a template object
$new_object->setData($data); // set the info.
$this->items[] = $new_object; // Add to the collection.
}
}
If car was not such a complex object it would be easier, because I could pass the car fqcn as a parameter for carCollection and use it in every iteration. But that’s not possible for a very complex object (or if I want to instantiate different sub types of the object - for example: lorry, pick-up, van…- depending on information from the database).
The question.
Regarding the collection being aware about the container: does not it break the purpose of the DIC phylosophy?
I guess not on one side, because I am using PSR\Container to type hint the container I pass to the collection (which loosens the coupling). But it breaks the idea that the container should not be coupled with the domain model at all.
The only alternative that I have thought about is substituting the creation of one new object for each iteration with a cloning from a prototype object that lives in the collection as a property. But we all know cloning in php can get really tricky and very difficult to debug (Or worse: very difficult to even know that there is a problem going on).
Similar issue.
PS: I have the same problem when I try to do lazy loading using Porxy objects: I need the proxy objects to have access to the container if I want to instantiate the full object later, which also breaks the principles of a DiC.
Thank you all.
I think the core of your issue comes down to this:
The issue comes when I try to use a method that populates the collection with all the cars that exist in the database.
The composition of object graphs of application components should be independent of any I/O, as described here and here by Mark Seemann. This means that the structure of those object graphs can't (and shouldn't) change based on changes in your database.
It seems to me that your Car object is a Domain Object, rather than a (Domain) Service. It would, therefore, be better suited to return a collection of Car instances from a service, rather than injecting the collection directly into one of your application components.
I need the proxy objects to have access to the container if I want to instantiate the full object later, which also breaks the principles of a DiC.
It's generally considered to be a bad practice to let application code depend on the DI Container. This a a pattern known as the Service Locator anti-pattern. There are many reasons why Service Locator is considered to be a bad idea, but it's important to understand that the list of downsides of Service Locator do not apply when the DI Container is used in the application's startup path (a.k.a. the Composition Root). A DI Container used within the Composition Root, is not an implementation of the Service Locator anti-pattern.
When your proxy classes are defined within the Composition Root, it's perfectly fine to let them depend on the DI Container and you won't violate any software principle or practice.
Related
I am building a MVC application with Zend Framework. The Model includes separate Domain and Mapper layers, and a Service layer sits on top.
For some of my Domain objects, when I create a new instance I need to create other Domain objects which are composed by the first object. For example, when I create a new Organisation object I might add an Employee object (based on the current user), and a Location object (based on the current user's location).
So far I have been creating these in the constructor of the parent object (in this case, Organisation). This is OK, however it does create unnecessary dependencies between Organisation and it's children.
I would prefer to create the children in the Service layer, but am I letting myself in for trouble if I do this?
After reading Martin Fowlers (POEAA) chapter on the Service Layer, I think it comes down to whether this is Domain Logic or Application/Workflow logic. Seems to me that it's borderline... (Note that my service layer is already more than just a facade).
As I understand from your description, currently both the Employee and Location are mandatory dependencies for every instance of Organization. When you are creating this dependencies in the constructor, you create two problems here (thy are kinda like two ends of same ugly stick):
The Organization class becomes tightly coupled to the names of "Employee" and "Location"
It becomes very hard to test the behavior of Organization instances, because you have no direct control over its dependencies. You are unable to isolate the "unit under test".
Note A: actually an organization require a collection of employees/members, with minimum number of one. In this case a collection of domain objects would seem like a better choice from bit aspects of logic and API implementation.
To avoid these problems there are two solution for situation when you have to create a complicated object graph:
Use a factory (supplemented by properly implemented DIC), which creates all the requirements of your Organization class and injects them, when you are constructing new instance.
Create the create all the dependencies and then inject them manually in the Organization, when instantiating the object.
Note B: to create domain any domain objects within a service you should be using a factory for said objects. To facilitate this, you would have to inject a domain object factory in the constructor of any service, that you instantiate. Otherwise you just end up with classes that are coupled to names of other classes.
The choice would depend on what else you want to do with the Employee EmployeeCollection and Location instances in that and similar cases and on what style you prefer.
If you are doing extensive and very specific manipulation with these dependencies, then they should definitely be instantiated separately (via a simple domain object factory) and only then injected. If you are only creating an object graph, the the DIC-based factory would be favorable solution.
P.S.: I would recommend for you to watch the The Clean Code Talks - Don't Look For Things! lecture.
I am trying to use Dependency Injection as much as possible, but I am having trouble when it comes to things like short-lived dependencies.
For example, let's say I have a blog manager object that would like to generate a list of blogs that it found in the database. The options to do this (as far as I can tell) are:
new Blog();
$this->loader->blog();
the loader object creates various other types of objects like database objects, text filters, etc.
$this->blogEntryFactory->create();
However, #1 is bad because it creates a strong coupling. #2 still seems bad because it means that the object factory has to be previously injected - exposing all the other objects that it can create.
Number 3 seems okay, but if I use #3, do I put the "new" keywords in the blogEntryFactory itself, OR, do I inject the loader into the blogEntryFactory and use the loader?
If I have many different factories like blogEntryFactory (for example I could have userFactory and commentFactory) it would seem like putting the "new" keyword across all these different factories would be creating dependency problems.
I hope this makes sense...
NOTE
I have had some answers about how this is unnecessary for this specific blog example, but there are, in fact, cases where you should use the Abstract Factory Pattern, and that is the point I am getting at. Do you use "new" in that case, or do something else?
I'm no expert, but I'm going to take a crack at this. This assumes that Blog is just a data model object that acts as a container for some data and gets filled by the controller (new Blog is not very meaningful). In this case, Blog is a leaf of the object graph, and using new is okay. If you are going to test methods that need to create a Blog, you have to simultaneously test the creation of the Blog anyway, and using a mock object doesn't make sense .. the Blog does not persist past this method.
As an example, say that PHP did not have an array construct but had a collections object. Would you call $this->collectionsFactory->create() or would you be satisfied to say new Array;?
In answer to the title: yes, abstract factories typically use new. For example, see the MazeFactory code on page 92 of the GoF book. It includes, return new Maze; return new Wall; return new Room; return new Door;
In answer to the note: a design that uses abstract factories to create data models is highly suspect. The purpose is to vary the behavior of the factory's products while making their concrete implementations invisible to clients. Data models with no behavior do not benefit from an abstract factory.
I'm trying to understand the factory design pattern.
I don't understand why it's good to have a middleman between the client and the product (object that the client wants).
example with no factory:
$mac = new Mac();
example with a factory:
$appleStore = new AppleStore();
$mac = $appleStore->getProduct('mac');
How does the factory pattern decouple the client from the product?
Could someone give an example of a future code change that will impact on example 1 negative, but positive in example 2 so I understand the importance of decoupling?
Thanks.
I think it has to do with the resources needed to construct some types of objects.
Informally, if you told someone to build a Mac, it would be a painstaking process that would take years of design, development, manufacturing, and testing, and it might not be done right. This process would have to be repeated for every single Mac. However, if you introduce a factory, all the hard work can be done just once, then Macs can be produced more cheaply.
Now consider Joomla's factory.php. From what I can tell, the main purpose of JFactory is to pool objects and make sure objects that should be the same aren't copied. For instance, JFactory::getUser() will return a reference to one and only one object. If something gets changed in that user object, it will appear everywhere. Also, note that JFactory::getUser() returns a reference, not a new object. That is something you simply cannot do with a constructor.
Often, you need local context when constructing an object, and that context may persist and possibly take on many forms. For instance, there might be a MySQL database holding users. If User objects are created with a constructor, you'll need to pass a Database object to the constructor (or have it rely on a global variable). If you decide to switch your application to PostgreSQL, the semantics of the Database object may change, causing all uses of the constructor to need review. Global variables let us hide those details, and so do factories. Thus, a User factory would decouple the details of constructing User objects from places where User objects are needed.
When are factories helpful? When constructing an object involves background details. When are constructors better? When global variables suffice.
Don't know if I can put it any better than IBM did https://www.ibm.com/developerworks/library/os-php-designptrns/#N10076
This example returns an object of type Mac and it can never be anything different:
$mac = new Mac();
It can't be a subclass of Mac, not can it be a class that matches the interface of Mac.
Whereas the following example may return an object of type Mac or whatever other type the factory decides is appropriate.
$appleStore = new AppleStore();
$mac = $appleStore->getProduct('mac');
You might want a set of subclasses of Mac, each representing a different model of Mac. Then you write code in the factory to decide which of these subclasses to use. You can't do that with the new operator.
So a factory gives you more flexibility in object creation. Flexibility often goes hand in hand with decoupling.
Re your comment: I wouldn't say never use new. In fact, I do use new for the majority of simple object creation. But it has nothing to do with who is writing the client code. The factory pattern is for when you want an architecture that can choose the class to instantiate dynamically.
In your Apple Store example, you would probably want some simple code to instantiate a product and add it to a shopping cart. If you use new and you have different object types for each different product type, you'd have to write a huge case statement so you could make a new object of the appropriate type. Every time you add a product type, you'd have to update that case statement. And you might have several of these case statements in other parts of your application.
By using a factory, you would only have one place to update, that knows how to take a parameter and instantiate the right type of object. All places in your app would implicitly gain support for the new type, with no code changes needed. This is a win whether you're the sole developer or if you're on a team.
But again, you don't need a factory if you don't need to support a variety of subtypes. Just continue to use new in simple cases.
I'm starting a new project and setting up the base to work on. A few questions have risen and I'll probably be asking quite a few in here, hopefully I'll find some answers.
First step is to handle dependencies for objects. I've decided to go with the dependency injection design pattern, to which I'm somewhat new, to handle all of this for the application.
When actually coding it I came across a problem. If a class has multiple dependencies and you want to pass on multiple dependencies via the constructor (so that they cannot be changed after you instantiate the object).
How do you do it without passing an array of dependencies, using call_user_func_array(), eval() or Reflection? This is what i'm looking for:
<?php
class DI
{
public function getClass($classname)
{
if(!$this->pool[$classname]) {
# Load dependencies
$deps = $this->loadDependencies($classname);
# Here is where the magic should happen
$instance = new $classname($dep1, $dep2, $dep3);
# Add to pool
$this->pool[$classname] = $instance;
return $instance;
} else {
return $this->pool[$classname];
}
}
}
Again, I would like to avoid the most costly methods to call the class. Any other suggestions?
Also, how do I access the DI class inside classes, for example, in controllers that need to access different models? Should I call it statically or pass it along each class that would require it? I don't think the last idea is feasible.
Thanks everyone.
[Before I start, let me say that I'm mostly a Java programmer - with only a little bit of PHP knowledge. But I'll simply try to get the most important concepts across without language specifics.]
Dependency Injection is based on two parts of code:
Construction
Execution
In its most extreme shape, there are no new operators to be found in the Execution part. All of them are moved into the Construction part. (In practice, this will be toned down.)
All of the construction happens - in the Construction part. It creates the graph of objects needed for Execution bottom up. So let's assume, it should construct A:
A depends on B, and
B depends on C.
Then
C is constructed first.
Then B is constructed with C as a parameter.
Then A is constructed with B as a parameter.
So C doesn't have to be passed as a constructor parameter to A. This small example doesn't illustrate strongly enough, how much this reduces the amount of objects that have to be passed around to quite a small number.
The Dependency Injector itself should not be passed into the Execution part. This is one of the basic mistakes everyone (including myself) tries to make, when they first come in contact with DI. The problem is, that this would completely blur the lines between Construction and Execution. Another way to say it is, that it would violate the Law of Demeter. Or in pattern speak: It would eventually "degrade" the Dependency Injection pattern to the Service Locator pattern. It's debatable, if this is really a degradation, but in any case it's usually not a good idea to misuse the Dependency Injector as a Service Locator.
So whenever you need to give one of your constructed objects the capability to produce other objects during execution, instead of passing the Dependency Injector, you would only pass simple Providers (a term used by the Java DI framework Guice). These are rather simple classes that can only create a certain kind of object. They have similarities with a factory.
First try to pass the required dependencies directly to the constructor.
So, to sum it up:
Build objects bottom-up.
Only pass as few dependencies as required to create an object.
Once your done, start executing.
During execution, you can still fetch newly created objects by using Providers.
But don't take it too far: Simple objects can still be created without a Provider :-)
And now, all you'll have to do is to translate this stuff into quality code. Maybe others can help you out with a few PHP examples.
Addendum: A little bit more about Providers
As noted above, the notion "Provider" (a specialized factory) is a bit specific to the Java DI framework Guice. This framework can automatically create a Provider for any type of object. However, the concept is generally useful for DI. The only difference is, that without the help of Guice or a similar framework, you'll have to write the Providers yourself - but that's quite easy:
Let's say, B depends on C.
If B just needs one fixed instance of C, then you don't need a Provider - you can simply construct B with the constructor argument C.
If B needs to create more instances of C during execution, then just write a class called CProvider with a get() method, that can create a new instance of C. Then pass an instance of CProvider into the constructor of B, and store the Provider in an instance field of B. Now B can call cProvider.get() when it needs a new instance of C.
Providers are part of the Construction code, so you're allowed to use new C(...)! On the other hand, they're not part of the Execution code, so you shouldn't have any execution logic there.
CProvider can be passed into multiple constructors of course. You can also write multiple versions CProvider1, CProvider2, ... - where each can construct different versions of C objects with different properties. Or you simple instantiate CProvider multiple times with different arguments.
You should look into using an IOC container to manage your dependencies for you. A good IOC container should take care of passing dependencies between dependent contructors for you.
There is an existing question asking about IOC container options for PHP.
It looks like you are trying to roll your own dependency injection container. Why not use one that already exists, like Symfony, Crafty or Sphicy?
I'd like to:
Make commonly required services visible to all classes that need them,
with a minimum of boilerplate, and
without sacrificing testability!
It's a small project and I think DI might be overkill, but maybe I'm wrong? Anyhow, I have been focusing on the ServiceLocator pattern as described by Martin Fowler
In a client class' constructor, I have something like this:
this->db = Locator::getDb();
this->log = Locator::getLogger();
Then the rest of the class' methods access the service through those member attributes, e.g.:
this->fooModel = new fooModel(this->db);
fooItem1234 = this->fooModel->findById(1234);
However I would also like this level of visibility for "model" objects (like fooModel above) because they are accessed from several different places and there is no need to have more than one instance.
So my initial thought was to extend Locator to have a ::getFooModel() but now it seems I'm violating the Open/Closed Principle, since I'll have to modify Locator every time I introduce a new model class.
To satisfy OCP, I could use the Dynamic Service Locator (also described on Fowler's page) however I'm not totally sold on this for the same reasons as him, i.e. it's not explicit enough.
Another solution would be to just make all my models' methods static. So:
fooItem1234 = FooModel::findById(1234);
I like this because it's zero boilerplate. I can just create a new model class and start calling it from anywhere with a single line. But now the model depends on Locator to find its DB connection and I'm not sure how I feel about that. For one, if I ever needed to have two fooModels open on separate database connections, it would be a mess and/or impossible. That said, I don't actually need to do that currently so this option seems a little tempting.
Finally, there's DI. But like I said above I think it might be too much for this little project.
Conclusion: I'm a little stuck here and would appreciate some advice from the gurus of StackOverflow!
Why do you think that DI is overkill for your project? DI patterns such as Constructor Injection is way simpler and cleaner than Service Locator (which I consider an anti-pattern).
I consider Service Locator to be an anti-pattern since it is totally opaque to the user of the API which dependencies need to be in place; thus, one could easily invoke methods on your objects in a context where the Service Locator would throw, and the API gives you absolutely no clue that this is the case.
You don't need a DI Container to use DI. If just have a simple project, you can use what is known as Poor Man's DI where you wire up dependencies manually.
... and there is no need to have more than one instance.
You're mixing apples and oranges. The fact that you only need one instance of a class for an application, is not the same thing as it being a good idea to make that instance globally available. With DI you don't change the cardinality - there is still just one instance. What you change is the scope of variables that address said instance. There's a difference.