让我们考虑以下简化的Resource
层次结构:
public abstract class Resource {
static public boolean accepts(String resource);
}
public class AudioResource extends Resource {
static public boolean accepts(String resource) {
//Check if we can proceed this resource as audio
//Some complex logic there ...
}
}
public class VideoResource extends Resource {
static public boolean accepts(String resource) {
//Check if we can proceed this resource as video
//Another complex logic there
}
}
Resource
有几十个子类,数字也在增长。每个子资源:
现在,我们要创建一个工厂,它遍历所有可用的子类并创建一个接受资源的工厂(使用accepts
方法检查它)。
像这样的东西(让我们假设Java有静态方法多态):
public class ResourceFactory {
private static List<Class<Resource>> registry;
{
//Populate registry once on start
}
public static Resource createResource(String resource) {
for (Class<Resource> clazz : registry) {
if (clazz.accepts(resource))
return clazz.createInstance(resource);
}
}
}
不幸的是(或不是?),Java不支持多态静态方法。 考虑到这一点,设计Resource
和ResourceFactory
的可行方法是什么?
答案 0 :(得分:2)
您可以使用:
public interface Resource {
// some methods
}
public interface ResourceFactory {
boolean acceptsResource(String resource);
Resource createResource(String resource) throws UnsupportedResourceException;
}
public final MultiResourceFactory implements ResourceFactory{
private static final ServiceLoader<ResourceFactory > resourceFactoryLoader
= ServiceLoader.load(ResourceFactory .class);
private static final MultiResourceFactory INSTANCE;
private MultiResourceFactory(){
}
public static MultiResourceFactory getInstance(){
if (INSTANCE == null){
INSTANCE = new MultiResourceFactory();
}
return INSTANCE;
}
@Override
public boolean acceptsResource(String resource){
for (ResourceFactory resourceFactory : resourceFactoryLoader) {
if (resourceFactory.acceptsResource(resource)){
return true;
}
}
return false;
}
@Override
public Resource createResource(String resource) throws UnsupportedResourceException{
for (ResourceFactory resourceFactory : resourceFactoryLoader) {
if (resourceFactory.acceptsResource(resource)){
return resourceFactory.createResource(resource);
}
}
throw new UnsupportedResourceException(resource);
}
有关如何注册工厂的信息,请参阅ServiceLoader: http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
注意:代码未经测试