Java - реализация поставщика услуг

У меня есть следующий "шаблон" (не совсем по-настоящему признанный DP, но я часто использую его в своих решениях) в C#, цель которого - создать центральную точку реализации объекта, основанную на интерфейсах (своего рода Фабрика),

Доступ к нему осуществляется как одиночный, и пользователи запрашивают реализацию данного интерфейса и возвращают соответствующую реализацию.

Моя цель - перенести его на Java. У меня есть два прототипа решения, но я не совсем доволен результатами, так как на одном из них (более мощном и сложном) мне пришлось поместить много абстракций поверх механизмов создания экземпляров из-за общих ограничений Java и других хотя проще и гораздо менее мощным (он даже не может использовать преимущества дженериков - что может быть трудно в моей ситуации использования).

Я хотел бы использовать его в 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 ответ

Решение

Обычно это называется шаблоном ServiceLocator.

Я бы порекомендовал заранее построенное решение, такое как robo-guice.

Другие вопросы по тегам