对象层次结构的工厂(多态静态方法解决方法)

时间:2011-11-25 16:37:08

标签: java design-patterns

让我们考虑以下简化的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有几十个子类,数字也在增长。每个子资源:

  • 有一些逻辑来确定它是否接受资源。例如。它可以用regexp或其他东西解析资源URL;
  • 不是单身设计;

现在,我们要创建一个工厂,它遍历所有可用的子类并创建一个接受资源的工厂(使用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不支持多态静态方法。 考虑到这一点,设计ResourceResourceFactory的可行方法是什么?

1 个答案:

答案 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

注意:代码未经测试