что не так с простым контейнерным классом IOC? - PullRequest
0 голосов
/ 05 июня 2018

В прошлый день я реализовал простой класс, который служил бы контейнером 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 Ответ

0 голосов
/ 05 июня 2018

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

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

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

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

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

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

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

...