Search code examples
javafactoryfactory-pattern

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?


Solution

  • 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).