When I was first learning C++, I came across this article about factories, Pluggable C++ Factory, and ever since I've used that pattern for my factories in C++. Now, I've been doing Java recently and on more than one occasion I've wanted to use a factory, but I can't seem to figure out a way to extend the factory at compile time.
Any implementation of a factory I can think of in Java involves telling the actual factory class about all of the underlying classes, which is rather suboptimal.
So, how can I get all subclasses of a class to register themselves in a static dictionary at c开发者_如何学运维ompile time/program instantiation?
EDIT It seems that my question was too vague. Let me elaborate,
In Java if I were to try to replicate this pattern like so: Factory.java
abstract class Factory {
private static Dictionary<int, Factory> dict;
public Factory(int index) {
dict[int] = self;
}
public Foo getFoo(int index) {return dict[index].createFoo();}
protected abstract Foo makeFoo();
}
Derived.java
class Derived extends Factory {
public Derived() {super(DERIVED_INDEX);}
private static Derived tmp = new Derived();
public Foo makeFoo() {return new FooImplementation();}
}
The factory won't update with the reference to Derived (and thus won't create Derived instances) unless I manually register it myself, which defeats the purpose of having the static tmp member.
I think the ServiceLoader class can help you here.
Think of implementing Factory Method using Reflection.
You might find the Reflections library useful.
Using Reflections you can query your metadata such as:
* get all subtypes of some type
* get all types/methods/fields annotated with some annotation, w/o annotation parameters matching
* get all resources matching matching a regular expression
Using this library you can define an interface and a factory which can create any implementation of that interface (by searching for those implementations)
精彩评论