2012-01-19 11 views
5

Niedawno poznałem zalety wstrzyknięcia zależności, ale zastanawiam się, czy powinienem używać go w moim projekcie, ponieważ nie potrzebuję nawet pełnego mvc. Teraz, kiedy go używam, zdaję sobie sprawę z dodatkowego obciążenia na każdej stronie, którą piszę. Na przykład ...Czy powinienem używać zastrzyku zależności w moim projekcie 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; 
    } 
} 

... klasa konto będzie zawsze trzeba dB i sesję i będę zawsze tylko mają jedną klasę każda. Więc moje pytanie jest, powinien być używany DI w takiej sytuacji, czy mam po prostu użyć ...

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

Dependency Injection to nie tylko narzędzie MVC, to dobra praktyka w wielu różnych projektach, niezależnie od tego, czy korzystasz z frameworka, czy nie. –

+1

Niestety, nie zamierzałem sugerować, że tak jest, tylko że ten projekt go nie wymaga. – Isius

+0

Naprawdę możesz sprawić, że kod będzie znacznie czystszy, po prostu zaimplementujesz mechanizm ładujący, aby pozbyć się wszystkich wymagań (z wyjątkiem oczywiście konieczności autoloadera). – GordonM

Odpowiedz

6

Injection Injection nie ma nic wspólnego z MVC. Naprawdę dobrze jest ułatwić pisanie testów jednostkowych i ostatecznie odkryłem, że naprawdę myślę o zasobach, z których korzystam i czy ta implementacja powinna używać tego zasobu.

Osobiście nie widzę szkody w tworzeniu wstrzykiwanego obiektu, więc masz kilka linii, w których musisz utworzyć obiekt? Mówi użytkownikowi o wiele więcej o tym, co się dzieje. Wolałbym mieć jasność w porównaniu do magii.

Osobiście uważam, że większość bałaganu w kodzie pochodzi z oświadczeń require. Powiedziałbym, że autoloader rozwiąże część tego problemu.

Bardzo mi się podobało to Google Clean Code Talk on DI. Pomogło mi to w lepszym zrozumieniu koncepcji i korzyści.

+0

W przeszłości wielokrotnie oglądałem Google Talk. To jest naprawdę dobre! – Steven

0

W celu rozwiązania tego problemu wymyślono pojemniki iniekcyjne. Rozważmy:

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

Klasa DependencyInjectionContainer zajęłaby zastrzyk:

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

     // ... 
    } 
} 
1

Czytałaś o meritum wstrzykiwania zależności. Dlaczego zacząłeś go używać?

Czy to ze względu na możliwość zamiany tych konkretnych zależności na testy lub inne środowiska? Czy miał wyizolować i wyraźnie określić kolejność łańcucha zależności?

Załóżmy na przykład, że chcieliśmy wprowadzić różne klasy do celów testowych (zasługa DI, która spowodowała, że ​​go używam). Jak sobie z tym radzisz bez DI?

Sprawdź swoją klasę konta. Możesz albo zmodyfikować konstruktor za pomocą sprawdzenia if w pewnym predykacie testMode(), albo możesz zmodyfikować konstruktory Db i Session, albo możesz ewentualnie zmienić plik konfiguracyjny. Niezależnie od tego, jakie rozwiązanie nie jest dostępne, możesz z tym zrobić? A co z innymi zależnościami (emailer, logger, itp.)? Czy masz jakieś interfejsy do systemów zewnętrznych, które powinieneś wyśmiewać do testowania?

W każdym razie, odpowiedź może być taka, że ​​nie jesteś zadowolony z rozwiązania DI, a Twoja aplikacja jest na tyle mała, że ​​można nią zarządzać bez niego.Ale ważne jest, aby zadać sobie pytanie w każdym razie.

Podobnie, zastosuj tę samą linię pytań do innych zalet DI, które zmotywowały Cię do rozpoczęcia używania.

Czy masz jedno wystąpienie Db na koncie i inne w każdej innej klasie? Czy mógłbyś mieć tylko jedną instancję? DI pomaga w tym. Możesz mieć zajęcia singletonowe bez faktycznego kodowania ich jako singletonów, zawsze wstrzykując to samo wystąpienie.

Z ciekawości, dlaczego robisz zastrzyk uzależnienia zamiast używać biblioteki DI? Połowa korzyści z używania DI polega na tym, że jest on czysto pobierany przez implementacje innych osób. Napisz tylko odpowiedni kod i pozwól bibliotekom zadbać o wykonanie zastrzyku dla ciebie. Jest to podobne do sugestii drrcknlsn, ale bez pisania rzeczywistej implementacji klasy DependencyInjectionContainer:

$ account = DependencyInjectionContainer :: build ("Konto");

i dokręć resztę.

Dobra biblioteka DI powinna zobaczyć konstruktora konta, zdać sobie sprawę, że potrzebuje Db i sesji i maszerować w górę łańcucha konstruktorów (w tym przypadku kończy się tam, ponieważ oba mają puste konstruktory). Przekłada się to na posiadanie takiej samej ilości kodu, jak przypadek bez DI (plus argumenty konstruktora, bez wywołań do konstruktorów w środku, ale bez dodatkowych bzdur na górze), z wszelkimi korzyściami, które doprowadziły cię do DI w pierwszej kolejności.

Powiązane problemy