Michael Kohler
Michael Kohler

Reputation: 753

Inject Factories - How and why?

In a code review the following comments came up: "I think, you actually mean to inject the factory as an instance, so that you can rebind the factory if needed." and "important hint: Factories should not be static, but should be injected."

Test.java:

Foo foo = FooFactory.get(argument);

FooFactory.java:

public final class FooFactory {
    public static Foo get(String argument) {
        return new Foo();
    }
}

How should I have done it otherwise? What does "rebind" mean in the first comment of the reviewer?

Upvotes: 2

Views: 3422

Answers (2)

JB Nizet
JB Nizet

Reputation: 691715

By doing what you did, you basically ignored dependency injection, and used a static factory instead. So, if in a unit test, you want your factory to return fake instances of Foo rather than real instances, you can't.

Instead, you should use dependency injection (Spring example here):

public class SomeService
    private FooFactory fooFactory;

    @Autowired
    public SomeService(FooFactory fooFactory) {
        this.fooFactory = fooFactory;
    }

    public void someMethod(String arg) {
        Foo foo = fooFactory.create(arg);
        ...
    }
    ....
}

And now, in a unit test, you can inject whatever FooFactory implementation you want (typically, a mock).

Upvotes: 8

Perception
Perception

Reputation: 80603

With most dependency injection frameworks you can bind a particular object implementation at run time. I would wager that is what the reviewer is referring too. To take advantage of this you would, of course, have to inject your factory as opposed to statically creating it.

Upvotes: 3

Related Questions