Vytváření instancí sebe sama
- Petr Hanák
- Člen | 10
Ahoj,
jak řešit vytváření instancí v souladu s DI?
Jde mi o objekty jednoho typu, ale s jinými parametry – např. položky
v nákupním košíku.
Napadlo mě tohle řešení, je to něco na způsob inline továrničky.
<?php
class Polozka extends \Nette\Object{
private $db;
public function __construct(\Nette\Database\Context $db)
{
$this->db = $db;
}
public function get()
{
return new self($this->db);
}
}
?>
Je to good-practice to řešit takto? Jak to vyřešit lépe?
- Šaman
- Člen | 2666
Jde to vyřešit lépe. I když, princip je vlastně stejný.
Tahle třída, kterou jsi popsal, je továrni třída, nazveme ji třeba
PolozkaFactory (bylo by ale lépe nepoužívat češtinu, pak vznikají
takovéhle patvary). Tu si zaregistruješ jako DI službu (o předání
databáze se postadá kontejner) a injectuješ kamkoliv, kde budeš potřebovat
instance třídy Položka. Pokud přejmenuji Polozku na Item, tak:
<?php
class Item extends \Nette\Object
{
private $db;
public function __construct(\Nette\Database\Context $db)
{
$this->db = $db;
}
# veškerá dalši logika týkající se vnitřních záležitostí položky
}
class ItemFactory extends \Nette\Object
{
private $db;
public function __construct(\Nette\Database\Context $db)
{
$this->db = $db;
}
public function create() # konvence dovoluje i get(), ale create je výstižnější
{
# veškerá případná logika týkající se vytváření položky
return new Item($this->db);
}
}
?>
Výhoda tohoto přístupu je ta, že DI kontejner ti umí jednoduchou továrničku vygenerovat sám a odpadne nutnost psát třídu ItemFactory. To popíšu odpoledne, teď už nemám čas. Zatím to můžeš udělat takhle, tak to totiž vnitřně opravdu funguje. Pak můžeš ItemFactory vymazat a místo toho to přepsat přímo do configu (a Nette si ji na pozadí vytvoři samo).
P.S. Ještě zvaž, jestli položka potřebuje databázi, pravděpodobné je máš jako ActiveRecord, který se moc nedoiporučuje. To už ale nesouvisí s dotazem.
Editoval Šaman (13. 10. 2014 14:11)
- mkoubik
- Člen | 728
Je to OK. Pokud potřebuješ jen takhle jednoduchou továrničku (jen předávání závislostí do nových instancí), tak si ji můžeš nechat vygenerovat z interface.