pátek 11. ledna 2013

Dependency injection není pouze o jednoduším testování

V sítu služby GetPrismatic mi uvízly články na témá dependency injection a to konkrétně Dependency injection is not a virtue (David Heinemeier Hansson), The DI Opposition a Dependency injection and other Java necessary evils. Pointa těchto článků je v tom, že v staticky typovaných jazycích, jako je například Java, se používá dependency injection z důvodů snazší testovatelnosti. David Heinemeier Hansson uvádí jako příklad vytvoření instance konkretního typu např.Date date = new Date();, které je nemožné mockovat. Ten samý problém v dynamicky typovaných jazycích odpadá, protože je možné překrýt konstruktor a tím pádem podstrčit mock. Z toho autoři vyvozují, že dependency injection není pro dynamicky typované jazyky potřeba, a dokonce by se mělo pokládata za anti-pattern.

Dynamické jazyky, a vlastně jakýkoliv jazyk, který vám v daném kontextu umožní překrýt daný konstruktor, bezesporu testování ulehčuje. Háček je v tom, že jednoduchost testování je pouze jedním z přínosů dependency injection. Mnohem zásadnější přínos je rozvolnění vazeb mezi objekty, což je samozřejmě mimo rozlišovací schopnost dynamicky typovaných jazyků. Mezi další přínosy patří kontextové řízení vazeb, jinými slovy, v závislosti na kontextu potřebuji jeden a ten samý typ, ale pokaždé jinak nastavený. Dalším přínosem je řízení životního cyklu objektů (singleton, prototyp) a jejich vazeb. Jednoduchý příklad s vytvořením datumu svádí k zamítnutí dependency injection, ale pro složitější případy, kdy se jedná více propojených objektů s různou konfigurace, davá dependency injection perfektně smysl. To už nemluvím o tom, že část konfigurace je možné díky dependency injection externalizovat úplně mimo kód aplikace.

V staticky typovných jazycích má dependency injection a Inversion of Control nezastupitelné místo. Má ho bezesporu i v dynamicky typovaných jazycích, jenom to není z důvodů jednoduchosti testování, ale z dalších důvodů, o kterých jsem mluvil. Tyto důvody jsou totiž nezávislé na typovosti daného jazyka.