Dependency injection – 2 nejasnosti

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Azathoth
Člen | 495
+
0
-

Zdravím, mám 2 nejasnosti ohledně Dependency Injection:

  1. jak poznám, kdy si musím na služby psát továrničku a přidávat ji do kontejneru a kdy stačí službu zaregistrovat v config.neon?
  2. když mám interface IDatabase a třídu Database implementující interface IDatabase, mohu použít při získávání databáze toto?
<?php
    public function __construct(IDatabase $database) {  //interface jako hint
        $this->database = $database;
    }
?>

nebo to musí být takhle?

<?php
    public function __construct(Database $database) {  //třída jako hint
        $this->database = $database;
    }
?>

Předem děkuji za všechny konstruktivní odpovědi.

Editoval Azathoth (31. 7. 2014 19:23)

Michal Vyšinský
Člen | 608
+
0
-

Ahoj,

To jestli potřebuješ továrničku nebo stačí normální služba vyplyne z toho, jestli potřebuješ jen jednu sdílenou instanci, nebo chceš vždy dostat novou nezávislou instanci. Také se dobře pozná, že potřebuješ továrničku, když potřebuješ mít nějakou službu konfigurovatelnou, ale v každé části aplikace jinak.

Takže na komponenty a formuláře je vždy lepší továrnička. Ale například cache chceš mít vždy jen jako jednu službu, takže se zaregistruje jako běžná služba.

Co se týče druhého bodu, tak je vždy lepší použít interface. Můžeš kdykoliv vyměnit jednu službu jinou třídou (která implementuje IDatabase) a vše by mělo fungovat – pokud důsledně dodržuješ to, že používáš metody definované v interface.

Azathoth
Člen | 495
+
0
-

Takže u té závislosti implementující interface dám konkrétní třídu pouze do config.neon jako service a pouze tam to vyměním, když chci použít jinou třídu implementující stejný interface?

Michal Vyšinský
Člen | 608
+
+3
-

Přesně tak.

Typicky můžeš mít interface ILogger, který budeš vyžadovat všude, kde potřebuješ něco logovat. Kam se to bude logovat (a jestli vůbec někam), ti může být úplně jedno.

Můžeš mít nějaký FileLogger, který implementuje ILogger a zaregistruješ jej do kontejneru. V tuto chvíli se ti bude vše logovat do souboru.

Když najednou nechceš nic logovat (třeba na localhostu), můžeš mít NullLogger, který také implementuje ILogger ale jeho metody mohou být naprosto prázdné, důležité je pouze to, aby tam byly – implementovali interface. Snadno pak změníš jednu jedinou věc v konfiguraci (neon) a o nic víc se starat nemusíš.

Toto se dá naučit z praxe a návrhových vzorů – k tomu mohu doporučit například tento článek http://www.zdrojak.cz/…ncipy-solid/

Editoval Michal Vyšinský (31. 7. 2014 19:54)