Что не так с простым контейнерным классом IOC?

В прошлый день я реализовал простой класс, который будет служить контейнером IOC (не очень) в одном из моих игровых проектов, и один профессиональный парень сказал мне, что у него будут некоторые проблемы при тестировании кода (слишком жаль, чтобы поделиться тем, что именно проблема!!)

хотя я всегда использую фреймворки МОК, я хотел знать, почему именно эта методология плоха?

Я даже написал много тестов (используя фиктивные фреймворки), используя эту методологию, и у меня никогда не было проблем.

Я хочу вашу идею о проблемах дизайна этого:

public class IocContainer{

  private static IocContainer instance;

  private IocContainer(){
  }

  public static IocContainer getInstance()
  {
    if(instance == null){
      instance = new IocContainer();
    }
    return instance;
  }

  public ChatPresenter getChatPresenter(ChatView chatView)
  {
    return new ChatPresenterImpl(chatView, getChatRepo() , getMessagingService());
  }

  private ChatRepo getChatRepo()
  {
    return new ChatRepoImpl(getDbHelper(), getRemoteService());
  }

  private MessagingService getMessagingService()
  {
    return new MessagingServiceImpl()
  }

  private DbHelper getDbHelper()
  {
    return new DbHelperImpl();
  }

  private RemoteService getRemoteService()
  {
    return new RemoteServiceImpl();
  }
}

как вы видите, я сделал доступным только getChatPresenter, и я использую это, как показано ниже, и это работает хорошо.

ChatPresenter presenter = IocContainer.getInstance().getChatPresenter(this)

код обрабатывает инверсию управления без какой-либо жесткой связи (используя интерфейсы).

Я хочу знать что-то не так с этим подходом? (Я хочу получить ответы с технической точки зрения, потому что я уже знаю, что с помощью библиотеки контейнеров Ioc проще иметь больше функций, таких как области и т. Д.)

На самом деле я хочу знать какие-либо проблемы и ограничения, которые этот подход будет делать в будущем?

будь жестоким и убей меня:D

1 ответ

Решение

Подводя итог комментария след:

Ваш подход похож на указатель службы, как описано здесь Мартином Фаулером: http://martinfowler.com/articles/injection.html

Между тем, что описывает Мартин, и вашим кодом есть большая разница: ваш код напрямую создает экземпляры ваших сервисов и, таким образом, является скорее фабрикой, чем реестром.

Основная идея / цель инверсии контроля состоит в том, чтобы уменьшить связывание за счет уменьшения зависимостей, чего не происходит, если ваш контейнер зависит от реализаций службы (которые ему нужно напрямую вызывать конструкторами). Таким образом, реализация в вашем вопросе несколько противоречит этой основной идее.

Одним из недостатков зависимости от реализаций является то, что службы не могут быть заменены без перекомпиляции контейнера. Это может не быть проблемой, если вы, скорее всего, никогда не будете иметь разные реализации, но если вам это может понадобиться, реестр служб будет более полезным.

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

Реестр обычно сопровождается некоторыми средствами для настройки реестра, например, через файлы конфигурации или сканирование пути к классам (автоматический поиск присутствующих плагинов). Тем не менее, может быть достаточно написать код, который настраивает реестр. Все зависит от того, от какой связи вам нужно избавиться (чтобы решить проблему, с которой вы столкнулись) и какая связь приемлема.

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