Использование Dependency Injection или есть более простые решения? - PullRequest
1 голос
/ 19 октября 2011

В нашем проекте у нас есть класс KnowledgeBaseManager, который используется другими классами следующим образом:

KnowledgeBaseManager manager = KnowledgeBaseManager.get();
manager.foo();

KnowledgeBaseManager содержит статическую переменную standardKnowledgeBaseManager, которая инициализируется при первом использовании:

class KnowledgeBaseManager {
  private static KnowledgeBaseManager standardKnowledgeBaseManager = null;
  public static KnowledgeBaseManager get() {
    if (standardKnowledgeBaseManager == null) {
      standardKnowledgeBaseManager = new KnowledgeBaseManager();
      // initialize  standardKnowledgeBaseManager with appropriate knowledge base
    }
    return standardKnowledgeBase;
 }

Кроме того, у нас есть параметризованный конструктор

public static KnowledgeBaseManager get(OntModel model) {...}

, который мы используем до сих пор только для модульного теста, где нам нужен KnowledgeBaseManager с базой знаний теста в фоновом режиме.

Теперь перед нами стоит следующая задача: для разработки мы хотим, чтобы приложение использовало KB-менеджер с другой базой знаний в фоновом режиме (из-за скорости).Чтобы быть более конкретным, мы создаем веб-приложение с Wicket.Поэтому мы хотим объявить где-то в начале приложения, какая база знаний и KnowledgeBaseManager используются в приложении (в зависимости от того, где мы находимся в процессе разработки или развертывания).Код для использования KB-менеджера (например,

 KnowledgeBaseManager manager = KnowledgeBaseManager.get(); 

сейчас) не должен быть изменен для этого.

Вопрос в том, какая архитектура лучше для этого?

Я думал об использовании структуры внедрения зависимостей, такой как PicoContainer или Guice, но у меня нет никакого опыта с этим, и я не уверен, будет ли это накладными расходами для этой конкретной проблемы.Какие-либо предложения для лучших практик в нашем случае?

Ответы [ 2 ]

2 голосов
/ 20 октября 2011

Вы реализуете одноэлементный шаблон - и если ваш код является многопоточным, вы реализуете его неправильно (см. http://java.sun.com/developer/technicalArticles/Programming/singletons/)

Более того, как вы обнаружили, синглтоны (то есть глобальные переменные) плохо для тестирования.Инъекция зависимости - один из ответов.Сначала игнорируйте все рамки.Это означает, что вы пишете свой KnowledgeBaseManager традиционным способом - класс с конструктором и методами, без статических одноэтапно-факторизованных методов.Код, использующий KnowledgeBaseManager, не создает или просматривает KnowledgeBaseManager, а скорее получает его через конструктор или метод установки (я предпочитаю первый):

public class ClassUsingKnowledgeBaseManager {

  protected final KnowledgeBaseManager knowledgeBaseManager;

  public ClassUsingKnowledgeBaseManager(KnowledgeBaseManager knowledgeBaseManager) {
    this.knowledgeBaseManager = knowledgeBaseManager;
  }

  // ...

}

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

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

Но для многих программ,Вы могли бы написать код в стиле DI без использования DI-рамки.

0 голосов
/ 19 октября 2011

Вы можете использовать шаблон конструкционного дизайна.

Вы можете создать фабрику и настроить ее так, чтобы она возвращала нужные вам объекты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...