2012-03-06 113 views
0

在C#中,我有以下“模式”(不是真正意义上的DP),但我倾向于在我的解决方案中使用它,其目标是实现对象实现的中心点提供基于接口(某种工厂)。Java - 服务提供者的实现

它以单身形式访问,用户请求给定接口的实现并返回适当的实现。

我的目标是将其迁移到Java。我有两个函数原型解决方案,但我不是很满意的结果,因为他们(更强大的&复杂)之一,我不得不把很多抽象的实例化机制的顶部,由于Java的泛型的局限性和其他尽管简单也不那么强大(它甚至不能利用泛型 - 在我的使用情况下可能是hany)。 。

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

ServiceFactory.getInstance()addService(IMyInterface.class,新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; 
    } 
} 

爪哇(更简单和不太强大的解决方案)

@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

这通常被称为Service Locator pattern

我会推荐一个预先构建的解决方案,如robo-guice

+0

谢谢,Rasmus!我其实忘记说我打算在Android应用程序中使用它。因为这样的春天可能不是答案。我曾与guice工作过,但没有遵循它,因此必须检查它是否支持Android。 Pico对我来说是未知的,所以我将不得不检查它。 – 2012-03-06 11:49:36

+0

@Diesel Heart:那么考虑看robo-guice吧。 – 2012-03-06 12:10:15

+0

是的!非常感谢,Rasmus。我在回答你之后不久就在谷歌上找到了RoboGuice。总之,你对我的服务定位器的Java实现任何意见(让我们把它作为现在纯粹的学术运动)? – 2012-03-06 12:32:42

相关问题