Внедрение зависимостей PHP для дочерних классов - PullRequest
2 голосов
/ 22 ноября 2011

Я пытаюсь выяснить лучшие практики для внедрения зависимостей в PHP.

Вопрос: Нужно ли вводить все зависимости подкласса в родительский класс?Я использую термины «родитель» и «ребенок» в терминах композиционных отношений.

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

Редактировать:

Ниже приведен более конкретный пример того, о чем я говорю.MyClassA не требуется объект подключения к базе данных или регистратор.Однако DoSomething эти объекты действительно нужны.Каков наилучший способ получить подключение к базе данных и регистратор для экземпляра DoSomething?Я не хочу использовать одиночные объекты или глобальные объекты для модульного тестирования.Кроме того, этот пример используется только для классов.Что если есть 3 или 4, а 3-му или 4-му нужен какой-то экземпляр объекта, а первым 2 или 3 - нет?MyClassA просто передает объект следующему и т. Д.?

class MyClassA {
  protected $_doSomethingObject;

  public function doSomething()
  {
    return $this->_doSomethingObject()->doSomethingElse();
  }

  public function setDoSomethingObject($doSomethingObject)
  {
    $this->_doSomethingObject = $doSomethingObject;
  }
}

class DoSomething {
  protected $_logger;
  protected $_db;

  public function doSomethingElse()
  {
     $this->_logger->info('Doing Something');
     $result = $this->_db->getSomeDataById();
     return $results;
  }

  public function setLogger($logger)
  {
     $this->_logger = $logger;
  }

  public function setDBConection($db)
  {
     $this->_db = $db;
  }
}

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

    $logger = new Logger();
    $db = new DBConnection();    

    $doSomething = new DoSomething();
    $doSomething->setLogger($logger);
    $doSomething->setDBConnection($db);

    $a = new MyClassA();
    $a->setDoSomething($doSomething);

Ответы [ 2 ]

1 голос
/ 22 ноября 2011

Если это так, то лучше всего работать задом наперед, так сказать ...?

Да.Как я упоминал в комментарии, вы сначала настраиваете большинство внутренних объектов.

Если объект создает внутри себя другой объект, который не открыт, то он может передать свои внедренные объекты, если это необходимо.Например:

class DoSomething {
// ...
  public function foo() {
    $foo = new Foo();
    $foo->setLogger($this->_logger);
    return $foo->bar();
  }
}

Однако, если этот секретный объект Foo нуждался в ссылках на другие вещи, которых DoSomething не было, то у вас проблемы с дизайном.Если это произойдет, вам нужно сделать все, что нужно:

  • Вставить объект foo в родительский объект перед вызовом foo().
  • Вставить эту зависимость в родительский объектперед вызовом foo().
  • Добавьте зависимость в качестве аргумента функции.
  • Рефакторинг кода в лучшем дизайне, который не создает этой проблемы.
0 голосов
/ 22 ноября 2011

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

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