Vytváření instancí sebe sama

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

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
+
+1
-

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
+
0
-

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.