Java - реализация поставщика услуг - PullRequest
0 голосов
/ 06 марта 2012

У меня есть следующий «шаблон» (на самом деле это не совсем признанный 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 Ответ

1 голос
/ 06 марта 2012

Обычно это называется шаблон локатора службы .

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

...