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();
- the loader object creates various other types of objects like database objects, text filters, etc.
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…
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
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.