Отказ от ответственности: я просто изучаю DI самостоятельно. Возьми ответ с крупицей соли.
Внедрение зависимостей составляет всего около Внедрение зависимостей . Если ваш объектно-ориентированный дизайн приводит к тому, что объект Family
несет ответственность за создание экземпляров Member
, то, безусловно, объект Family
создает Member
, потому что в этом случае Member
равен больше не считается зависимостью Family
, а ответственность . Поэтому:
class Family
{
/**
* Constructor.
*
* Since you have decided in your OO design phase that this
* object should have the responsibility of creating members,
* Member is no longer a dependency. MySQLi is, since you need
* it to get the information to create the member. Inject it.
*
*/
public function __construct($id, MySQLi $mysqli)
{
$this->id = $id;
$this->mysqli = $mysqli;
}
/**
* Query the database for members data, instantiates them and
* return them.
*
*/
public function getMembers()
{
// Do work using MySQLi
}
}
Но если подумать, действительно Family
действительно должен нести ответственность за создание Member
? Лучшим дизайном будет иметь другой объект, такой как FamilyMapper
create Family
со своими членами. Как это:
class FamilyMapper
{
/**
* Constructor.
*
* A better OO design, imho is using the DataMapper pattern.
* The mapper's responsibility is instantiating Family,
* which means it's going to have to connect to the database,
* which makes MySQLi its dependency. So we inject it.
*
*/
public function __construct(MySQLi $mysqli)
{
$this->mysqli = $mysqli;
}
public function findByID($familyID)
{
// Query database for family and members data
// Instantiate and return them
}
}
class Family
{
/**
* Constructor.
*
* Family is an object representing a Family and its members,
* along with methods that *operate* on the data, so Member
* in this OO design is a dependency. Inject it.
*
*/
public function __construct($id, MemberCollection $members)
{
$this->id;
$this->members;
}
public function getMembers()
{
return $this->members;
}
}
Используя этот шаблон, ваши доменные объекты вместе с их методами (которые могут содержать бизнес-логику) будут отделены от вашего кода доступа к данным. Это хорошая вещь в внедрении зависимостей - она заставляет вас переосмыслить свой дизайн ОО, чтобы вы в итоге получили более чистый код.
Многие думают, что использование внедрения зависимостей означает не использование фабрик и тому подобное. Это неправильно! Внедрение зависимостей составляет всего лишь Внедрение зависимостей . Вы также можете использовать внедрение зависимостей с объектами фабрики, внедряя зависимости в фабрику вместо того, чтобы фабрика создавала свою собственную зависимость.
Полезные ссылки:
- http://martinfowler.com/articles/injection.html
- У кого-нибудь есть хорошая аналогия для внедрения зависимости?
- Как объяснить введение зависимости 5-летнему ребенку?
Дополнения * +1051 *
Опять же, возьмите то, что находится ниже, с зерном соли.
Обратите также внимание, что существует разница между инъекцией зависимости и контейнером ввода зависимости . Первый - это простая концепция внедрения зависимостей вместо того, чтобы объекты создавали их сами (что приводит к очень высокой связи). Мы видим это из приведенного выше примера.
Последний термин для фреймворков / библиотек, которые имеют дело с внедрением зависимостей, поэтому вам не нужно делать ручное внедрение. Ответственность контейнера заключается в подключении зависимостей, поэтому вам не нужно делать грязную работу. Идея заключается в том, что вы определяете конфигурацию внедрения зависимостей, которая сообщает контейнеру, что есть у объекта Foo
зависимостей и как их внедрить. Контейнер читает документацию и выполняет инъекцию за вас. Это то, что делают библиотеки DIC, такие как Pimple, SimpleDIC.
Вы можете сравнить контейнеры внедрения зависимостей с фабриками, поскольку оба являются объектами создания, единственной обязанностью которых является создание объектов. Хотя фабрики часто являются специализированными (т. Е. FamilyMemberFactory
создает экземпляры MemberInterface
), контейнер внедрения зависимостей является более общим. Некоторые люди говорят, что использование контейнера внедрения зависимостей освобождает вас от необходимости в фабриках, но вы должны помнить, что это означает, что вы должны создавать и поддерживать файлы конфигурации внедрения зависимостей, которые могут содержать тысячи строк XML / PHP.
Надеюсь, это поможет.