2012-01-19 4 views
5

Я недавно узнал о преимуществах инъекции зависимостей, но мне интересно, должен ли я использовать его в своем проекте, так как мне даже не требуется полномасштабный mvc. Теперь, когда я его использую, я понимаю дополнительные накладные расходы на каждой странице, которую я пишу. Например ...Должен ли я использовать инъекцию зависимостей в моем проекте php?

require_once '../../include/session.class.php'; 
    require_once '../../include/db.class.php'; 
    require_once '../../include/account.class.php'; 

    $objSession = new Session(); 
    $objDb  = new Db(); 
    $objAccount = new Account($objSession, $objDb); 

account.class.php

class Account { 
    ... 
    public function __construct(Session $objSession, Db $objDb) { 
     $this->session = $objSession; 
     $this->db = $objDb; 
    } 
} 

... класс счета всегда нужно Db и сессии, и я только когда-либо один класс каждого. Так что мой вопрос, я должен использовать DI в такой ситуации, или я должен просто использовать ...

account.class.php

require_once '../../include/session.class.php'; 
require_once '../../include/db.class.php'; 

class Account { 
    ... 
    public function __construct() { 
     $this->session = new Session(); 
     $this->db = new Db(); 
    } 
} 

...?

+5

Injection Dependency предназначен не только для MVC, это хорошая практика во множестве проектов, независимо от того, используете ли вы фреймворк или нет. –

+1

Извините, не предполагал, что это так, только этот проект не требует этого. – Isius

+0

Вы действительно могли бы сделать код намного более чистым, просто внедряя автозагрузчик, чтобы вы могли отбросить все требуемые (за исключением необходимости для автозагрузчика, конечно). – GordonM

ответ

6

Зависимость Инъекции не имеет ничего общего с MVC. Это действительно хорошо, когда упростить запись модульных тестов и, в конечном итоге, я обнаружил, что он заставляет меня действительно думать о ресурсах, которые я использую, и должна ли эта реализация использовать этот ресурс.

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

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

Мне очень понравилось Google Clean Code Talk on DI. Это помогло мне понять концепцию и ее преимущества немного лучше.

+0

Я смотрел этот Google Talk несколько раз в прошлом. Это действительно хорошо! – Steven

0

Конкретные контейнеры для инъекций были изобретены для решения этой самой проблемы. Рассмотрим:

$account = DependencyInjectionContainer::build('Account'); 

DependencyInjectionContainer класс будет обрабатывать инъекции:

public static function build($class) { 
    switch ($class) { 
     case 'Account': 
      $session = new Session(); 
      $db = new Db(); 
      return new Account($session, $db); 

     // ... 
    } 
} 
1

Вы читали о достоинствах инъекции зависимостей. Почему вы начали использовать его?

Это связано с возможностью замены этих конкретных зависимостей для тестирования или в разных средах? Было ли это изолировать и сделать явным порядок круговой цепи зависимостей?

Предположим, например, что было желание вводить разные классы для целей тестирования (заслуга DI, которая заставила меня использовать его). Как вы справляетесь с этим без DI?

Посмотрите на свою учетную запись. Вы можете либо изменить конструктор с помощью проверки if на предикате testMode(), либо вы можете изменить конструкторы Db и Session, или вы можете изменить файл конфигурации. Независимо от решения без DI, которое вы выбираете, вы в порядке? Как насчет других зависимостей (почтовый сервер, регистратор и т. Д.)? Есть ли у вас какие-либо интерфейсы для внешних систем, которые вы должны высмеивать для тестирования?

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

Аналогичным образом примените ту же линию допроса к другим достоинствам DI, которые побудили вас начать использовать его.

Кстати, у вас есть один экземпляр Db в учетной записи и еще один в каждом из ваших других классов? У вас есть только один экземпляр? DI помогает с этим. Вы можете иметь одноэлементные классы, фактически не кодируя их как одиночные, всегда вставляя один и тот же экземпляр.

Из любопытства, почему вы делаете свою собственную инъекцию зависимостей вместо использования библиотеки DI? Половина преимуществ использования DI заключается в том, что он чисто абстрагируется от реализации других людей. Только напишите код, который вам нужен, и пусть библиотеки позаботятся о том, чтобы сделать инъекцию для вас. Это похоже на предложение drrcknlsn, но без написания фактической реализации класса DependencyInjectionContainer:

$ account = DependencyInjectionContainer :: build ('Account');

и навинтить остальные.

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