0

I am writing a Factory class that depending on a given parameter would return various implementations of an interface:

class Factory {
 public MyType getType(String param) {
  if (param.equals("A")) {
     return new MyTypeA();
   } else if (param.equals("B")) {
     return new MyTypeB();
 } 
}

Now instead of new I want to leverage Spring's dependency injection capabilities. I want to use @Annotation based autowiring.

First thing coming to mind is to use @Autowire on field like so:

class Factory {
@Autowired
private MyTypeA myTypeA;
@Autowired
private MyTypeB myTypeB;
         public MyType getType(String param) {
          if (param.equals("A")) {
             return myTypeA;
           } else if (param.equals("B")) {
             return myTypeB;
         } 
        }

But then I remember that field autowiring is not recommended because it is hard to unit test such classes.

Next thing I could try would be to use setter level autowiring to allow for testing:

class Factory {
private MyTypeA myTypeA;
private MyTypeB myTypeB;
         public MyType getType(String param) {
          if (param.equals("A")) {
             return myTypeA;
           } else if (param.equals("B")) {
             return myTypeB;
         } 

@Autowired
public void setMyTypeA(MyTypeA a) {
 this.myTypeA = a;
}

@Autowired
public void setMyTypeB(MyTypeB b) {
 this.myTypeB = b;
}
}

OK this looks better, but wait, there is more - I want my class to be immutable so I want my private fields to be final and only get populated at constructor time. So next thing I could try would be constructor based injection:

class Factory {

private final MyTypeA myTypeA;
private final MyTypeB myTypeB;

public Factory(MyTypeA myTypeA, MyTypeB myTypeB) {
 this.myTypeA = myTypeA;
 this.myTypeB = myTypeB;
}

         public MyType getType(String param) {
          if (param.equals("A")) {
             return myTypeA;
           } else if (param.equals("B")) {
             return myTypeB;
         } 
        }

Looks good, but here comes the question - if I have 20 different types I can return from this factory depending on the param value, I can't create a 20 param constructor.

Please suggest, what would be the best approach in this case (trying to avoid xml based autowiring).

Thank you

0 Answers