#5 panika
Na první pohled se může zdát, že pokud máš obrovský projekt, čeká tě šílené množství konfigurací (abys nakonfiguroval každou třídu). Realita je ovšem jiná. Nakonfigurovat musíš pouze takové třídy, u nichž není předem známo, co se bude vkládat do hodnot konstruktoru.
Existují ovšem třídy, které konfiguraci vůbec nepotřebují, například nemají v konstruktoru žádné parametry. Faktorky jsou jedním z těchto tříd.
class Car
{
}
class MyCarFactory
{
public function __construct() { }
public function createCar()
{
return new \Car();
}
}
Pokud bys chtěl takovou faktorku používat v servisní vrstvě, pak na základě DI musíš faktorku nějakým způsobem předat, nejčastěji v __construct metodě.
class CarService
{
/** @var \MyCarFactory
private $carFactory;
/**
* @param \MyCarFactory $carFactory
*/
public function __construct(\MyCarFactory $carFactory)
{
$this->carFactory = $carFactory;
}
public function foo()
{
$car = $this->carFactory->createCar();
}
}
Ačkoliv máš servisní třídu, která používá faktorku na auta, Dice ti tuto servisní třídu vytvoří úplně jednoduchým zápisem.
$dice->create('\CarService');
Tento postup je možný, protože pro vytvoření CarService potřebuješ pouze třídu MyCarFactory, která ovšem k jejímu vytvoření nepotřebuje žádnou konfiguraci. To Dice přes reflexi rozpozná. Samozřejmě ne vždycky vytváříš třídu, která žádnou konfiguraci nemá.
Zpravidla ti mohou nastat dvě situace:
- Vytváříš třídu, která ve svém konstruktoru nemá další třídy, ale přímo konkrétní parametry (stringy, čísla, atp.)
- Chceš získat konkrétní implementaci nějakého rozhraní
V obou těchto případech potřebuješ vytvořit nějakou konfiguraci, například pomocí nějakého XML souboru, jak jsi psal. V této konfiguraci pak budeš mít uvedeny vstupní parametry, které se mají do vytvářené třídy vkládat.
Má to několik plus:
- konfiguraci máš na jedno místě a máš o ní přehled
- jsi nucen dodržovat DI, následkem čehož jsi schopen psát unit testy oddělené od funkčnosti zbytku aplikace
- nemusíš psát vlastní faktorky pro vytváření procesů a servisních služeb
Obecně vzato, pokud se rozhodneš použít nějaký DIC jako třeba diskutovaný Dice, pak, jak už jsem psal, by o něm měla být zmínka pouze v bootstrapperu, ale tvá doména by již měla být založena na samotných objektech a službách, které jsi namodeloval ty.