Skip to content

Commit

Permalink
di: added FAQ
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Mar 28, 2023
1 parent d693f34 commit 2cbb99c
Show file tree
Hide file tree
Showing 51 changed files with 1,938 additions and 0 deletions.
1 change: 1 addition & 0 deletions dependency-injection/bg/@home.texy
Expand Up @@ -8,6 +8,7 @@ Dependency Injection е шаблон за проектиране, който щ
- [Глобално състояние и единични елементи |global-state]
- [Предаване на зависимости |passing-dependencies]
- [Какво е DI контейнер? |container]
- [Често задавани въпроси |faq]


Nette DI
Expand Down
1 change: 1 addition & 0 deletions dependency-injection/bg/@left-menu.texy
Expand Up @@ -4,6 +4,7 @@
- [Глобално състояние и единични елементи |global-state]
- [Прехвърляне на зависимостта |passing-dependencies]
- [Какво е контейнер DI? |container]
- [Често задавани въпроси |faq]


Nette DI
Expand Down
112 changes: 112 additions & 0 deletions dependency-injection/bg/faq.texy

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dependency-injection/cs/@home.texy
Expand Up @@ -8,6 +8,7 @@ Dependency Injection je návrhový vzor, který zásadně změní váš pohled n
- [Globální stav a singletony |global-state]
- [Předávání závislostí |passing-dependencies]
- [Co je DI kontejner? |container]
- [Často pokládané otázky|faq]


Nette DI
Expand Down
1 change: 1 addition & 0 deletions dependency-injection/cs/@left-menu.texy
Expand Up @@ -4,6 +4,7 @@ Dependency Injection
- [Globální stav a singletony |global-state]
- [Předávání závislostí |passing-dependencies]
- [Co je DI kontejner? |container]
- [Často pokládané otázky|faq]


Nette DI
Expand Down
112 changes: 112 additions & 0 deletions dependency-injection/cs/faq.texy
@@ -0,0 +1,112 @@
Často pokládané otázky o DI
***************************


Je DI jiným názvem pro IoC?
---------------------------

*Inversion of Control* (IoC) je princip, který se týká toho, kdo iniciuje volání – volá váš kód framework, nebo je váš kód zasunut do frameworku, který jej pak volá zpět?
IoC je obecný koncept, který zahrnuje [události|nette:glossary#Události] i takzvaný [Hollywoodský princip|application:components#Hollywood style].
Sem také patří továrny, o kterých hovoří [Pravidlo č. 3: nech to na továrně |introduction#Pravidlo č. 3: nech to na továrně], a které představují inverzi pro operátor `new`.

*Dependency Injection* (DI) se zaměřuje na způsob, jakým se jeden objekt dozví o jiném objektu, tedy o závislosti. Jde o návrhový vzor, který požaduje explicitní předávání závislostí mezi objekty.

Lze tedy říci, že DI je specifickou formou IoC. Nicméně ne všechny formy IoC jsou vhodné z hlediska čistoty kódu. Například mezi antivzory patří techniky, které pracují s [globálním stavem |global-state] nebo takzvaný [Service Locator |#Co je to Service Locator].


Co je to Service Locator?
-------------------------

Jde o alternativu k Dependency Injection. Funguje tak, že vytvoří centrální úložiště, kde jsou registrovány všechny dostupné služby nebo závislosti. Když objekt potřebuje závislost, požádá o ni Service Locator.

Oproti Dependency Injection však ztrácí na transparentnosti: závislosti nejsou objektům předávány přímo a nejsou tak snadno identifikovatelné, což vyžaduje prozkoumání kódu, aby byly všechny vazby odhaleny a pochopeny. Testování je také složitější, protože nemůžeme jednoduše předávat mock objekty testovaným objektům, ale musíme na to jít přes Service Locator. Navíc, Service Locator narušuje návrh kódu, jelikož jednotlivé objekty musí o jeho existenci vědět, což se liší od Dependency Injection, kde objekty nemají povědomí o DI kontejneru.


Kdy je lepší DI nepoužít?
-------------------------

Nejsou známy žádné obtíže spojené s použitím návrhového vzoru Dependency Injection. Naopak získávání závislostí z globálně dostupných míst vede k [celé řadě komplikací |global-state], stejně tak používání Service Locatoru.
Proto je vhodné využívat DI vždy. To není dogmatický přístup, ale jednoduše nebyla nalezena lepší alternativa.

Přesto existují určité situace, kdy použití globálních objektů může být oprávněné. Například při ladění kódu, kdy potřebujete v konkrétním bodě programu vypsat hodnotu proměnné, změřit dobu trvání určité části programu nebo zaznamenat zprávu.
V takových případech, kdy jde o dočasné úkony, které budou později z kódu odstraněny, je legitimní využít globálně dostupný dumper, stopky nebo logger. Tyto nástroje totiž nepatří k návrhu kódu.


Má používání DI své stinné stránky?
-----------------------------------

Obnáší použití Dependency Injection nějaké nevýhody, jako například zvýšenou náročnost na psaní kódu nebo zhoršený výkon? Co ztrácíme, když začneme psát kód v souladu s DI?

DI nemá na výkon nebo paměťové nároky aplikace vliv. Určitou roli může hrát výkon DI Containeru, avšak v případě [Nette DI |nette-container] je kontejner kompilován do čistého PHP, takže jeho režie při běhu aplikace je v podstatě nulová.

Při psaní kódu bývá nutné vytvářet konstruktory přijímající závislosti. Dříve to mohlo být zdlouhavé, avšak díky moderním IDE a [constructor property promotion |https://blog.nette.org/cs/php-8-0-kompletni-prehled-novinek#toc-constructor-property-promotion] je to nyní otázkou několika sekund. Továrny lze snadno generovat pomocí Nette DI a pluginu pro PhpStorm kliknutím myší.
Na druhou stranu odpadá potřeba psát singletony a statické přístupové body.

Lze konstatovat, že správně navržená aplikace využívající DI není v porovnání s aplikací využívající singletony ani kratší ani delší. Části kódu pracující se závislostmi jsou pouze vyňaty z jednotlivých tříd a přesunuty na nová místa, tedy do DI kontejneru a továren.


Jak legacy aplikaci přepsat na DI?
----------------------------------

Přechod z legacy aplikace na Dependency Injection může být náročný proces, zejména u velkých a komplexních aplikací. Je důležité přistupovat k tomuto procesu systematicky.

- Při přechodu na Dependency Injection je důležité, aby všichni členové týmu rozuměli principům a postupům, které se používají.
- Nejprve proveďte analýzu stávající aplikace a identifikujete klíčové komponenty a jejich závislosti. Vytvořte plán, které části budou refaktorovány a v jakém pořadí.
- Implementujte DI kontejner nebo ještě lépe použijte existující knihovnu, například Nette DI.
- Postupně refaktorujte jednotlivé části aplikace, aby používaly Dependency Injection. To může zahrnovat úpravy konstruktorů nebo metod tak, aby přijímaly závislosti jako parametry.
- Upravte místa v kódu, kde se vytvářejí objekty se závislostmi, aby místo toho byly závislosti injektovány kontejnerem. To může zahrnovat použití továren.

Pamatujte, že přechod na Dependency Injection je investice do kvality kódu a dlouhodobé udržitelnosti aplikace. Ačkoli může být náročné provést tyto změny, výsledkem by měl být čistší, modulárnější a snadno testovatelný kód, který je připraven pro budoucí rozšíření a údržbu.


Proč se upřednostňuje kompozice před dědičností?
------------------------------------------------
Je vhodnější používat kompozici místo dědičnosti, protože slouží k opětovnému použití kódu, aniž bychom se museli starat o důsledky změn. Poskytuje tedy volnější vazbu, kdy nemusíme mít obavy, že změna nějakého kódu způsobí potřebu změny jiného závislého kódu. Typickým příkladem je situace označovaná jako [constructor hell |passing-dependencies#Constructor hell].


Lze použít Nette DI Container mimo Nette?
-----------------------------------------

Rozhodně. Nette DI Container je součástí Nette, ale je navržen jako samostatná knihovna, která může být použita nezávisle na ostatních částech frameworku. Stačí ji nainstalovat pomocí Composeru, vytvořit konfigurační soubor s definicí vašich služeb a poté pomocí několika řádků PHP kódu vytvořit DI kontejner.
A ihned můžte začít využívat výhody Dependency Injection ve svých projektech.

Jak vypadá konkrétní použití včetně kódů popisuje kapitola [Nette DI Container |nette-container].


Proč je konfigurace v NEON souborech?
-------------------------------------

NEON je jednoduchý a snadno čitelný konfigurační jazyk, který byl vyvinut v rámci Nette pro nastavení aplikací, služeb a jejich závislostí. Ve srovnání s JSONem nebo YAMLem nabízí pro tento účel mnohem intuitivnější a flexibilnější možnosti. V NEONu lze přirozeně popsat vazby, které by v Symfony & YAMLu nebylo možné zapsat buď vůbec, nebo jen prostřednictvím složitého opisu.


Nezpomaluje aplikaci parsování NEON souborů?
--------------------------------------------

Byť se soubory NEON parsují velmi rychle, na tomto hledisku vůbec nezáleží. Důvodem je, že parsování souborů proběhne pouze jednou při prvním spuštění aplikace. Poté se vygeneruje kód DI kontejneru, uloží se na disk a spustí se při každém dalším požadavku, aniž by bylo nutné provádět další parsování.

Takto to funguje v produkčním prostředí. Během vývoje se NEON soubory parsují pokaždé, když dojde ke změně jejich obsahu, aby vývojář měl vždy aktuální DI kontejner. Samotná parsování je, jak bylo řečeno, otázkou okamžiku.


Jak se dostanu ze své třídy k parametrům v konfiguračním souboru?
-----------------------------------------------------------------

Mějme na paměti [Pravidlo č. 1: nech si to předat |introduction#Pravidlo č. 1: nech si to předat]. Pokud třída vyžaduje informace z konfiguračního souboru, nemusíme přemýšlet, jak se k těm informacím dostat, místo toho si o ně jednoduše požádáme - například prostřednictvím konstruktoru třídy. A předání uskutečníme v konfiguračním souboru.

V této ukázce je `%myParameter%` zástupný symbol pro hodnotu parametru `myParameter`, který se předá do konstruktoru třídy `MyClass`:

```php
# config.neon
parameters:
myParameter: Some value

services:
- MyClass(%myParameter%)
```

Chcete-li předávat více parametrů nebo využít autowiring, je vhodné [parametry zabalit do objektu |best-practices:passing-settings-to-presenters].


Podporuje Nette PSR-11: Container interface?
--------------------------------------------

Nette DI Container nepodporuje PSR-11 přímo. Nicméně, pokud potřebujete interoperabilitu mezi Nette DI Containerem a knihovnami nebo frameworky, které očekávají PSR-11 Container Interface, můžete vytvořit [jednoduchý adaptér |https://gist.github.com/dg/7f02403bd36d9d1c73802a6268a4361f], který bude sloužit jako most mezi Nette DI Containerem a PSR-11.
1 change: 1 addition & 0 deletions dependency-injection/de/@home.texy
Expand Up @@ -8,6 +8,7 @@ Dependency Injection ist ein Entwurfsmuster, das die Art und Weise, wie Sie Code
- [Globaler Zustand & Singletons |global-state]
- [Übergabe von Abhängigkeiten |passing-dependencies]
- [Was ist ein DI-Container? |container]
- [Häufig gestellte Fragen |faq]


Nette DI
Expand Down
1 change: 1 addition & 0 deletions dependency-injection/de/@left-menu.texy
Expand Up @@ -4,6 +4,7 @@ Injektion von Abhängigkeiten
- [Globaler Zustand & Singletons |global-state]
- [Übergabe von Abhängigkeiten |passing-dependencies]
- [Was ist ein DI-Container? |container]
- [Häufig gestellte Fragen |faq]


Nette DI
Expand Down

0 comments on commit 2cbb99c

Please sign in to comment.