2012-03-06 75 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

相關問題