Java 对象层次结构的工厂(多态静态方法解决方案) 让我们考虑下面的简化资源< /代码>层次结构: 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 } }

Java 对象层次结构的工厂(多态静态方法解决方案) 让我们考虑下面的简化资源< /代码>层次结构: 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 } },java,design-patterns,Java,Design Patterns,Resource有几十个子类,而且数量还在增长。每个次级资源: 有一些逻辑来确定它是否接受资源。例如,它可以用regexp或其他东西解析资源URL 不是设计上的独生子女 现在,我们想要创建一个工厂,它遍历所有可用的子类,并创建一个接受资源的工厂(使用accepts方法检查它) 类似这样(让我们假设Java有静态方法多态性): 公共类资源工厂{ 私有静态列表注册表; { //开始时填充注册表一次 } 公共静态资源createResource(字符串资源){ for(类类别:注册表){ if(分

Resource
有几十个子类,而且数量还在增长。每个次级资源:

  • 有一些逻辑来确定它是否接受资源。例如,它可以用regexp或其他东西解析资源URL
  • 不是设计上的独生子女
现在,我们想要创建一个工厂,它遍历所有可用的子类,并创建一个接受资源的工厂(使用
accepts
方法检查它)

类似这样(让我们假设Java有静态方法多态性):

公共类资源工厂{
私有静态列表注册表;
{
//开始时填充注册表一次
}
公共静态资源createResource(字符串资源){
for(类类别:注册表){
if(分类接受(资源))
返回clazz.createInstance(资源);
}
}    
}  
不幸的是(或者不是?),Java不支持多态静态方法考虑到这一点,设计
资源
资源工厂
的可能方法是什么?

您可以使用:

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);
  }   
公共接口资源{
//一些方法
} 
公共接口资源工厂{
布尔值acceptsResource(字符串资源);
资源createResource(字符串资源)引发UnsupportedResourceException;
}   
公共最终MultiResourceFactory实现ResourceFactory{
私有静态最终服务加载程序resourceFactoryLoader
=ServiceLoader.load(ResourceFactory.class);
私有静态最终多资源工厂实例;
私有多资源工厂(){
}
公共静态MultiResourceFactory getInstance(){
if(实例==null){
实例=新的MultiResourceFactory();
}
返回实例;
}
@凌驾
公共布尔值acceptsResource(字符串资源){
对于(ResourceFactory ResourceFactory:resourceFactoryLoader){
if(resourceFactory.acceptsResource(资源)){
返回true;
}
}
返回false;
}
@凌驾
公共资源createResource(字符串资源)引发UnsupportedResourceException{
对于(ResourceFactory ResourceFactory:resourceFactoryLoader){
if(resourceFactory.acceptsResource(资源)){
返回resourceFactory.createResource(资源);
}
}
抛出新的UnsupportedResourceException(资源);
}   
有关如何注册工厂的信息,请参阅ServiceLoader:


注意:代码未经测试

另一种方法是使用反射。
如何接受
可以是非静态的?在这种情况下,我们需要在每次需要检查时创建实例。您可以在其他位置创建实例,并将它们作为构造函数参数传递到调用方类代码中。反射肯定是一种方法,但我们没有重新定义在这种情况下,每个
资源
都需要一个接口。编写
资源
时根本不需要接受。从本质上说,它们变成了单例,但按惯例,而不是单例模式。这称为依赖项注入。感谢您的回答!因此,我们对每个
资源
强制执行一个工厂。我考虑过这一点虽然考虑到
ServiceLoader
的文档几乎描述了我需要的东西…可能,这是目前最好的解决方案。顺便说一句,你知道一些其他可能的设计方法吗?没有很多附加对象?(我指的是每个
资源
增加一个
ResourceFactory
)。
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);
  }