Reputation: 2307
I have a situation where my application can be in exactly one of a several "modes". Since these are discrete values I'd like to model them using an enum type.
With each state my application needs to perform a slightly different functionality, which I'd like to model using the plug-in pattern. I've defined an interface and provided a few implementations.
I'd now like my enumeration to return the plug-in that is appropriate for it's state. I'd like to do the following:
public enum Mode {
ONE {
@Override
public MyType get() { return factory.getFirst(); }
},
TWO {
@Override
public MyType get() { return factory.getSecond(); }
};
@Autowired private MyTypeFactory factory;
public abstract MyType get();
// Other methods removed for clarity
}
However this isn't going to work. This is because I'm using spring injection to add the plug-in factory to the enum (enum constants are static and spring injected variables are instance variables so I'll get a compilation error)
I can't create the MyType instances directly from the enum because they will require dependency injection
How do I get around this?
Upvotes: 4
Views: 5431
Reputation: 2307
This probably isn't the best solution (and I'd love to see something better suggested), but this is what I did in the end:
Modify the Factory so it reads:
public class MyTypeFactory {
private static MyTypeFactory me;
@PostConstruct
public void initialise() {
if (me == null) {
me = this;
}
}
public static MyTypeFactory getInstance() {
return me;
}
// The same code as before - getFirst(), getSecond() etc
}
So, a (singleton) spring managed bean that looks a bit like an old GOF singleton! The important difference is that there is a publicly accessible default (no argument) constructor
I can then modify my enum to read:
public enum Mode {
ONE {
@Override
public MyType get() { Factory.getInstance().getFirst(); }
},
TWO {
@Override
public MyType get() { Factory.getInstance().getSecond(); }
};
public abstract MyType get();
// Other methods removed for clarity
}
The enum can get access the factory via the static getInstance method when get() is called
Upvotes: 5