Java - 服务提供者的实现

时间:2012-03-06 11:22:20

标签: java android generics design-patterns provider

我在C#中有以下“模式”(不是真正认可的DP,但我倾向于在我的解决方案中使用它),其目的是基于接口提供对象实现的中心点(某种类型)工厂)。

它作为单例访问,用户请求实现给定的接口并返回相应的实现。

我的目标是将其迁移到Java。我有两个原型解决方案,但我对结果不太满意,因为在其中一个(更强大和复杂)我必须在实例化机制之上放置大量抽象,因为Java的泛型限制和其他虽然更简单也不那么强大(它甚至不能利用泛型 - 在我的使用情况下这可能是hany。)

我想用以下方式在Java中使用它来注册新的实现:

ServiceFactory.getInstance()。addService(IMyInterface.class,new MyImplementation());

(MyImplementations实现IMyInterface的地方)。

遵循原始C#版本和两个Java版本:

C#代码

public class ObjectProvider<ObjectType, BaseObjectType> : IObjectProvider<BaseObjectType>
   where ObjectType : BaseObjectType, new()
{

  public BaseObjectType ObjectInstance
  {
    get { return (BaseObjectType)new ObjectType(); }
  }
}

public class ServiceManager
{
  private static Dictionary<Type, object> _providersList = null;
  private static object _listLocker = new object();

  private ServiceManager() { }

  private static void InicializeProvidersList()
  {
    _providersList = new Dictionary<Type, object>();

    _providersList.Add(typeof(IMyType), new ObjectProvider<MyImplementation, IMyType>());
       ...
   }

   private static Dictionary<Type, object> ProvidersList
   {
     get
        {
            lock (_listLocker)
            {
                if (_providersList == null)
                    InicializeProvidersList();
                return _providersList;
            }
        }
    }

    public static BusinessType GetBusinessClass<BusinessType>()
    {
        Dictionary<Type, object> list = ProvidersList;
        Type pretendedType = typeof(BusinessType);
        if (!list.ContainsKey(pretendedType))
            return default(BusinessType);
        IObjectProvider<BusinessType> provider = list[pretendedType] as  IObjectProvider<BusinessType>;
        return provider.ObjectInstance;
    }
}

Java(更强大的解决方案)代码

public interface IInstantiator 
{
  <BaseObjectType> BaseObjectType getInstance(Object... args);
  void setCacheable(boolean value);
}

public abstract class BaseInstantiator <BaseObjectType, ObjectType extends BaseObjectType>  implements IInstantiator
{
   protected Class<ObjectType> objectType; 
   protected boolean isCacheable = true;
   protected BaseObjectType cache;

   public BaseInstantiator(Class<ObjectType> objectType)
   {
     this.objectType = objectType;
   }

   public void setCacheable(boolean value)
   {
     this.isCacheable = value;
   }

   @SuppressWarnings("unchecked")
   public final BaseObjectType getInstance(Object... args)
   {
     if(isCacheable && cache != null)
     {
       return cache;
     }
     else
     {
        BaseObjectType objectType = createInstance(args);

        if(isCacheable)
        {
          cache = objectType;
        }

        return objectType;
     }
  }

  protected abstract BaseObjectType createInstance(Object... args);
}

public class Instantiator <BaseObjectType, ObjectType extends BaseObjectType> extends      BaseInstantiator <BaseObjectType, ObjectType> 
{

  public Instantiator(Class<ObjectType> ot)
  {
    super(ot);
  }

  @Override
  protected BaseObjectType createInstance(Object... args)
  {
     try 
     {
       return objectType.newInstance();
     }
     catch (InstantiationException e) 
     {
        e.printStackTrace();
     }
     catch (IllegalAccessException e) 
     {
        e.printStackTrace();
     }

     return null;
  }
}


public class ServiceFactory 
{
  private HashMap<Class, IInstantiator> services;
  private static ServiceFactory instance;

  public <BaseObjectType> void addService(Class<BaseObjectType> baseObjectType, IInstantiator instantiator)
   {
     this.getServices().put(baseObjectType, instantiator);
   }

   @SuppressWarnings("unchecked")
   public <BaseObjectType> BaseObjectType getService(Class<BaseObjectType> baseObjectType, Object... args)
   {

     if(! getServices().containsKey(baseObjectType))
     {
        throw new NoSuchElementException("Unknown service interface!");
     }
     else
     {
       try 
       {
          return (BaseObjectType) getServices().get(baseObjectType).getInstance(args);
       } 
       catch (Exception e) 
       {
          return null;
       }
     }
   }

   private ServiceFactory () { }

   public static synchronized ServiceFactory getInstance()
   {

     if(ServiceFactory.instance == null)
     {
        ServiceFactory.instance = new ServiceFactory();
        populate();
     }

     return ServiceFactory.instance;
   }

   private static void populate()
   {
      //...
   }

   private HashMap<Class, IInstantiator> getServices() 
   {

     if(this.services == null)
     {
       this.services = new HashMap<Class, IInstantiator>();
     }

     return this.services;
   }
}

Java(更简单,功能更强大的解决方案)

@SuppressWarnings("rawtypes")
public class ManagerFactory
{
  private Map<Class, Object> managers;

  private ManagerFactory()
  {
    populateFactory();
  }

  private static class SingletonHolder
  {
    public static final ManagerFactory INSTANCE = new ManagerFactory();
  }

  public static ManagerFactory getInstance()
  {
    return SingletonHolder.INSTANCE;
  }

  private void populateFactory()
  {
    this.managers = new HashMap<Class, Object>();

    this.managers.put(ITaskManager.class, new TaskManager());
  }

  public Object getManager(Class interfaceClass)
  {
    if(this.managers.containsKey(interfaceClass))
      return this.managers.get(interfaceClass);
    else 
      return null;
  }
}

有人可以提供这方面的帮助吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

这通常称为Service Locator pattern

我建议使用预先构建的解决方案,例如robo-guice