I have recently started working on a Java project that is already with a sizeable codebase developed by a team over 3 months. I noticed that at many places , some objects they are instantiating directly in the constructor of the client object , rather than using a dependency injection. I wanted to refactor the object construction into a factory and use some injection framework.
I have created a factory that essentially is a one liner for a doing new <type(some params here)>. There is nothing fancy here - no singleton , no static factory pattern. Just a newInstance() method that returns a new instance of the dependency.
To show something in code :
class A { A() {
B bobj = new B(); // A and B are coupled directly
}
}
I want to refactor this to :
BFactory {
newInstance() { return new B(); // return B implementation }
}
class A {
A(BFactory factory){
B bobj = factory.newInstance(); // A does not know about B impl
}
}
My argument is that objects should not be created anywhere in the code except in a Factory meant for that purpose. This promotes loose coupling , otherwise you are coupling the two types tightly. One senior member ( the author of the code I am trying to refactor ) feels that the one liner factory is a over-complicating design.
Are there authoritative advices/references on patterns governing this problem ? Something that can be used to decide which approach is better and why exactly ?
One senior member ( the author of the code I am trying to refactor ) feels that the one liner factory is a over-complicating design.
This looks like the crux of your question and not whether you should be refactoring the code or not so let us answer it rather than deviating from the actual question. If we consider the examples that you present in your code, I agree with your colleague. You shouldn't be creating a factory class for each dependency you want to inject. There is nothing wrong with what you are trying to achieve but the way you try to achieve it is an overkill.
You either depend upon a hierarchy of Factory classes that know how to create each and every dependency or you depend on the actual class itself and have a Container that can wire the objects together for you.
Option 1 : Depend on a common Factory
class A {
B bobj;
C cobj;
A(Factory factory){
bobj = factory.createB();
cobj = factory.createC();
}
}
Option 2 : Depend on the dependency directly
class A {
B bobj;
C cobj;
A(A a,B b) {
this.bobj = b;
this.cobj = c
}
}
You can then create a Container class that knows how to wire objects together :
class Container {
public static B createB() {
return new BImpl();
}
public static C createC() {
return new CImpl();
}
public static A createA() {
return newAImpl(createB(),createC());
}
}
The examples presented above are way too basic. In the real world, you will mostly have a more complex graph of dependencies. That's where DI frameworks come in handy instead of reinventing the wheel. If your ultimate goal is to start using a DI framework, you could go with option 2 since DI frameworks achieve inversion of control by supplying dependencies to their clients rather than the client code asking for them.
Your underlying point is perfectly valid, it's usually not a good idea to instantiate objects directly in the constructor (they may be valid exceptions from that rule).
If you do this:
class Car {
private Engine engine;
public Car() {
engine = new Engine();
}
}
You will have a hard time testing the Car without the engine. You'll have to use reflection in order to exchange the instance by a mock.
If you do the following instead
class Car {
private Engine engine;
#Inject
public Car(Engine engine) {
this.engine = engine;
}
}
it is very easy to test the Car with a fake engine, replace the implementation of engine or change the way the engine should be constructed (e.g. add more parameters to the constructor).
But you should definitely use an established dependency injection framework instead of writing your own factories. If you pass in a "common factory" as Chetan suggested you end up hiding your dependencies.
Good resources for more motivation using dependency injection can be found here:
https://github.com/google/guice/wiki/Motivation or
https://youtu.be/acjvKJiOvXw (very good talk, should be worth your time).
Related
Background
I want to realize dependency injection in Python using injector (or pinject) which itself heavily borrows from guice. While an answer using Python/injector would be ideal, I'm also very happy about solutions/approaches that feature Java/guice.
Intention
I'll give you a quick summary of what I want to achieve: I have a component that depends on a list/sequence of other components that all implement the same interface. Those components have dependencies themselves which may vary amongst the different implementations. The concrete types (implementations) shall be configurable by the user (or using any mechanism of the DI framework).
Example
Yes, I've read Modules should be fast and side-effect free which suggests not to use an XML file for configuration, however as I don't know how to realize this within the framework I'll use one to demonstrate the dependency structure:
<RentingAgency>
<Vehicles>
<Car>
<DieselEngine></DieselEngine>
</Car>
<Car>
<PetrolEngine></PetrolEngine>
</Car>
<Bike></Bike>
</Vehicles>
</RentingAgency>
In this example there is a renting agency (the component that depends on a list of others) that rents out all kinds of vehicles (the interface). The specific vehicles in their fleet (in this case two cars and one bike) should be configurable but fixed during runtime. The vehicles themselves can have dependencies and they can be different depending on the type of vehicle (a car depends on a motor, a bike has no dependencies in this case).
Question
How can I construct the renting agency within the DI framework so that all required vehicles are injected and their dependencies resolved properly?
Maybe helpful
Multibinder
I've read about Multibinder (injector seems to have something similar with Binder.multibind) which allows for injecting a collection of objects that implement the same interface. However:
Can it be used to create multiple instances of the same class that need to receive different dependencies (the two cars (Class Car) in the example have different motors: Interface Motor, Class DieselEngine, class PetrolEngine)?
Using providers to accomplish that task seems to me like giving up the benefits of dependency injection: I could manually create the Car instances in the provider, passing the required Motor as argument, however because this pattern repeats further down the chain (i.e. multiple Motors of the same type are used and they also have dependencies) I want to use dependency injection for generating those objects too. But to manually use them in the provider it seems to me like I have to obtain the instances directly from the injector. The docs mention that injecting the injector is a rare case and from my understanding of dependency injection, the great benefit is that one can request a component and all dependencies are resolved by the framework automatically.
Also because I actually use Python I'm not sure if this approach is appropriate (as Python is quite flexible when it comes to dynamic code generation). Also injector.Injector.get.__doc__ mentions
Although this method is part of :class:Injector's public interface
it's meant to be used in limited set of circumstances.
For example, to create some kind of root object (application object)
of your application (note that only one get call is needed,
inside the Application class and any of its dependencies
:func:inject can and should be used):
Dependency injection frameworks are primarily for dependencies and because your Vehicles object is configured by the user at runtime it is more like application data than a dependency. It probably can't just be injected in one shot using MultiBinding unless you know it at compile time.
Likewise, you are right in saying that it would not be a good approach to construct your set of components by iterating and calling injector.getInstance(Bike.class) etc. For one, this is not good for testing.
However, because the objects contained in Vehicles have their own dependencies you can leverage the DI framework in the creation of your Vehicles object. Remember, also, that although you cannot bind a Provider to an implementation, when you bind a key Guice will inject that provider for you.
For the simple example in the post, consider creating a VehicleFactory. Inside, you could have something like the following:
public class VehicleModule implements Module {
#Override
public void configure(Binder binder) {
binder.bind(DieselEngine.class).toProvider(DieselEngineProvider.class);
binder.bind(PetrolEngine.class).toProvider(PetrolEngineProvider.class);
binder.bind(Bike.class).toProvider(BikeProvider.class);
}
}
public class DieselEngineProvider implements Provider<DieselEngine> {
#Inject
public DieselEngineProvider() {
//if DieselEngine has any dependencies, they can be injected in the constructor
//stored in a field in the class and used in the below get() method
}
#Override
public DieselEngine get() {
return new DieselEngine();
}
}
public class VehicleFactory {
private final CarFactory carFactory;
private final Provider<Bike> bikeProvider;
#Inject
public VehicleFactory(CarFactory carFactory, Provider<Bike> bikeProvider) {
this.carFactory = carFactory;
this.bikeProvider = bikeProvider;
}
public Bike createBike() {
return bikeProvider.get();
}
public Car createDieselCar() {
return carFactory.createDieselCar();
}
public Car createPetrolCar() {
return carFactory.createPetrolCar();
}
}
public class CarFactory {
private final Provider<DieselEngine> dieselEngineProvider;
private final Provider<PetrolEngine> petrolEngineProvider;
#Inject
public CarFactory(Provider<DieselEngine> dieselEngineProvider, Provider<PetrolEngine> petrolEngineProvider) {
this.dieselEngineProvider = dieselEngineProvider;
this.petrolEngineProvider = petrolEngineProvider;
}
public Car createDieselCar() {
return new Car(dieselEngineProvider.get());
}
public Car createPetrolCar() {
return new Car(petrolEngineProvider.get());
}
}
As you mention, there is the danger of this becoming 'factories all the way down', but Guice can help you here.
If the production of Engine becomes more complicated and involves a combination of different parameters, you can use tools like AssistedInject to auto-create the factories for you.
If you end up with a set of common dependencies and uncommon dependencies that you want to use to create different 'flavours' of an object then you have what is known as the robot legs problem then Guice can solve it using private modules.
Do note the following caveat from the Dagger 2 user guide:
Note: Injecting Provider has the possibility of creating confusing
code, and may be a design smell of mis-scoped or mis-structured
objects in your graph. Often you will want to use a factory or a
Lazy or re-organize the lifetimes and structure of your code to be
able to just inject a T.
If you follow this advice, it would seem that you would have to carefully balance using providers and using factories to create your Vehicle.
I find myself doing the following fairly regularly:
#Component
class FactoryOne {
public Object getNewMyThing() {
return new Object();
}
}
#Component
class FactoryTwo {
#Autowired
FactoryOne factoryOne;
public Object getNewMyThingTwo() {
Object one = factoryOne.getNewMyThing();
return new MyThingTwo(one);
}
}
FactoryOne does actually depend on JIT values to produce its object instance, although the example doesn't show this.
FactoryTwo is dependent on some JIT thing that factory one produces, however, whenever I write this code, I look at it and think "I must be able to let the DI framework handle this for me".
...is there a code pattern I can use to handle this?
(Example is in Spring, but happy for an answer in any DI framework)
In the project I'm working on (not my project, just working on it), there are many structures like this:
project.priv.logic.MyServiceImpl.java
project.priv.service.MyServiceFactoryImpl.java
project.pub.logic.MyServiceIF.java
project.pub.service.MyServiceFactoryIF.java
project.pub.service.MyServiceFactorySupplier.java
And the Service is called like this:
MyServiceFactorySupplier.getMyServiceFactory().getMyService()
I understand that a factory is used to hide the implementation of MyServiceImpl if the location or content of MyServiceImpl changes. But why is there another factory for my factory (the supplier)? I think the probability of my Factory and my FactorySupplier to change is roughly equal. Additionally I have not found one case, where the created factory is created dynamically (I think this would be the case in the Abstract Factory Pattern) but only returns MyServiceFactoryImpl.getInstance(). Is it common practice to implement a FactorySupplier? What are the benefits?
I can think of a couple of examples (some of the quite contrived) where this pattern may be useful. Generally, you have two or more implementations for your Services e.g.
one for production use / one for testing
one implementation for services accessing a database, another one for accessing a file base storage
different implementations for different locales (translations, formatting of dates and numbers etc)
one implementation for each type of database you want to access
In each of these examples, an initialization for your FactorySupplier is needed at startup of the application, e.g. the FactorySupplier is parametrized with the locale or the database type and produces the respective factories based in these parameters.
If I understand you correctly, you don't have any kind of this code in your application, and the FactorySupplier always returns the same kind of factory.
Maybe this was done to program for extensibility that was not needed yet, but IMHO this looks rather like guessing what the application might need at some time in the future than like a conscious architecture choice.
Suppose you have a hierarchy of classes implementing MyServiceIF.
Suppose you have a matching hierarchy of factory classes to create each of the instances in the original hierarchy.
In that case, MyServiceFactorySupplier could have a registry of available factories, and you might have a call to getMyServiceFactory(parameter), where the parameter determines which factory will be instantiated (and therefore an instance of which class would be created by the factory).
I don't know if that's the use case in your project, but it's a valid use case.
Here's a code sample of what I mean :
public class MyServiceImpl implements MyServiceIF
{
....
}
public class MyServiceImpl2 implements MyServiceIF
{
....
}
public class MyServiceFactoryImpl implements MyServiceFactoryIF
{
....
public MyServiceIF getMyService ()
{
return new MyServiceImpl ();
}
....
}
public class MyServiceFactoryImpl2 implements MyServiceFactoryIF
{
....
public MyServiceIF getMyService ()
{
return new MyServiceImpl2 ();
}
....
}
public class MyServiceFactorySupplier
{
....
public static MyServiceFactoryIF getMyServiceFactory()
{
return new MyServiceFactoryImpl (); // default factory
}
public static MyServiceFactoryIF getMyServiceFactory(String type)
{
Class serviceClass = _registry.get(type);
if (serviceClass != null) {
return serviceClass.newInstance ();
} else {
return getMyServiceFactory(); // default factory
}
}
....
}
I have a related hierarchy of classes that are instantiated by a hierarchy of factories. While I don't have a FactorySupplier class, I have in the base class of the factories hierarchy a static method BaseFactory.getInstance(parameter), which returns a factory instance that depends on the passed parameter.
I want to conduct a chain of processing elements and wire them together via Guice. Let's assume the following path:
interface A implemented by class AImpl needs some input
interface B implemented by class BImpl needs A
interface C implemented by class CImpl needs B
interface D implemented by class DImpl needs C
The dependency of A can only be resolved at runtime and not at configuration time. The usual approach would be to use Assisted Injection in this case to create a factory, that takes the missing instances as parameters, just like this:
public interface AFactory {
public A createA(String input);
}
But what I actually want is something like this:
public interface DFactory {
public D createD(String inputForA);
}
I don't want to manually pass AImpl-specific dependencies through the whole hierarchy.
Is it possible to achieve this with Guice? If not, what's the best way to circumvent this problem elegantly while still retaining benefits of injection?
Cheating way: Stick input in a static variable or singleton ThreadLocal. Set it before your pipeline starts and clear it after it ends. Bind everything else through DI.
Fancy way: In A, refer to a #PipelineInput String inputString but don't bind it in your main injector. Otherwise, bind dependencies as you normally would, including referring to #PipelineInput in other pipeline-related classes. When you do need a D, get it from your implementation of a DFactory, which I'm calling PipelineRunner.
public class PipelineRunner {
#Inject Injector injector; // rarely a good idea, but necessary here
public D createD(final String inputForA) {
Module module = new AbstractModule() {
#Override public void configure() {
bindConstant(inputForA).annotatedWith(PipelineInput.class);
}
};
return injector.createChildInjector(new PipelineModule(), module)
.getInstance(D.class);
}
}
Naturally, binding attempts for A, B, C, and D will fail outside of PipelineRunner for lack of a #PipelineInput String--you'll get a CreationException when you create the injector with those unsatisfied dependencies, as you discovered--but those pipeline-based dependencies should be easy to separate into a Module that you install into the child injector.
If this feels too hacky, remember that PrivateModules are also "implemented using parent injectors", and that the whole point of dependency injection is to make a dependency like inputForA available to the whole object graph in a decoupled way.
I see three options. They depend on how often you change the input for A .
1) Bind input as a constant in your module. This works only, if you know that value before you create the Injector and never want to change the value. See bindConstant
2) Use a private submodule which binds either A or the value for input inside that module. Basically you can have two or three instance graphs with different value. See newPrivateBinder.
3) Use a Scope ala RequestScope, SessionScope, ... This way you can change the input often but you must enter/leave the scope at some point to be defined. See Custom Scopes for an example.
So, I have implemented my business classes, where I pass in all dependencies via the constructor, so I can mock those out and easily unit test them. This works great so far, but then, at one point, I need to create an object graph out of those objects. For this, I'm using a static factory (I can't use a DI framework, sadly). Example:
public class FooBar {
public FooBar(Foo foo, Bar bar) {
this.foo = foo;
this.bar = bar;
}
}
public class Foo {
public Foo() {}
}
public class Bar {
public Bar(Foo foo) {
this.foo = foo;
}
}
public class GraphFactory {
public static FooBar newFooBar() {
Foo foo = new Foo();
Bar bar = new Bar(foo);
return new FooBar(foo, bar);
}
}
So, I'm not able to really test the GraphFactory (can't mock the dependencies), which is kinda ok (not much work is done here). But what if construction of the graph is more complex, i.e. it involves looking up some properties, doing JNDI lookups and so on?
Should I still not write a unit test for this? Is my class design maybe broken? Isn't the purpose of unit testing to test classes in isolation?
There is nothing wrong with this design and it is fully testable. If we focus on the single responsibilty of the factory -- it is responsible for assembling the object graph -- the tests for this are straight forward:
Set up the factory with its prerequisites.
Invoke the factory method.
Assert that the object was constructed to your requirements: default values are set, etc.
In the example above, foo, bar, and foobar are the result of the test and do not need to be mocked.
If the assembly of the object graph is more complex, and you need additional services to fetch data and check application settings, guess what happens? These dependencies are passed into the factory through its constructor. You should mock these dependencies to isolate the factory from its dependencies' dependencies. Consumers of your factory would receive a fully wired factory through their constructor; or the factory is assembled at application start-up and made available as a singleton, etc.
This is how DI works. It sounds peculiar because now you have to worry how the factory is created (and who created that object,etc, turtles all the way down) and this is a perfectly natural reaction.
That's why we have DI frameworks to assemble complex object graphs. In a well designed DI application, nothing should know how the graph was assembled. Akin to this design, nothing should know about the DI framework.
The only exception to that rule, is... (drum-roll)... a factory object!
Most DI frameworks will inject the DI container into an object if the object being resolved takes a DI in it's constructor. This greatly simplifies the factory's plumbing, and satisfies our design principles: no one knows how to construct our object except our factory and we've encapsulated knowledge of the DI container to key areas of the application that are responsible for object assembly.
Whew. Now, if you're still following along, how does this change our test? It shouldn't, at least not too much: step #1 changes slightly, where you fill the DI container with mock objects, and then construct the factory with the DI container.
As a matter of taste, some like to use auto-mocking DI containers during testing that will automatically generate mock dependencies when an item is requested. This can remove most of the set up pain.
If the newFooBar method had to be more complex, you could refactor out everything except for the creation of the Foo and the Bar into a package-private initialisation method. Then write tests for the initialisation method.
public class GraphFactory {
public static FooBar newFooBar() {
Foo foo = new Foo();
Bar bar = new Bar(foo);
FooBar toReturn = new FooBar(foo, bar);
initialise( toReturn );
return toReturn;
}
static void initialise( FooBar toInitialise ){
// some stuff here that you can test
}
}
You can't mock or stub static method calls but you can write a unit test for the factory without mocks.
But, why do you use static factory methods?. May be better to store the factory in a static variable if you want to access it in a static way.
You should give a look into Dependecy Injection, which will allow you get rid of the factory when used properly. I recommend you this video as an introduction, it helped me a lot:
http://code.google.com/p/google-guice/
It's an introduction to Guice, a library from google, but it will help you understand DI. Then you'll see how to replace all those 'new' with annotations, letting the library do all the work for you. Some people would recommend Sring instead, but i find Guice more friendly for beginners. I just hope this doesn't fire a Guice vs Spring discussion again :D