Super Trooper Component Factory (Invisible)

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

Dobrý večer,

vím, že továrnička na komponenty tady byla už hodněkrát. Nakonec se dostala do distribuce, takže si myslím, že tohle má taky naději :)

už dlouho hledám nejlepší (čti: nejméně pracnou) formu továrničky… prozatím jsem skončil na – prozatím nejkratším objeveném – způsobu použití:

pro začátek bych chtěl podotknout že veškeré komponenty mám v samostatných třídách. Pokud totiž komponenty vytvářím v presenteru, jdu jistým způsobem proti DRY (pokud nepočítám možnost použití takových komponent v potomcích presenteru), čemuž se snažím vyhnout.

<?php

public function createComponentMenu($name)
{
	return new Menu($this, $name);
}

?>

co to ještě zjednodušit?

<?php

{widget Menu}

?>

pokud existuje třída Menu – nechť se vytvoří její instance a normálním způsobem se zapojí do stromu komponent.

já používám následující implementaci:

<?php

// BasePresenter:


protected function createComponent($name)
{
	// Umí vytvořit komponentu bez volání createComponentFoo() - tahle funkce tedy nemusí existovat
	// Třídy v aktuálním namespacu mají přednost
	$class = $this->reflection->getNamespaceName() . '\\' . ucfirst($name);
	if (class_exists($class)) {
		return new $class($this, $name);
	}
	// Ale globální třídy taky bereme
	$class = '\\' . ucfirst($name);
	if (class_exists($class)) {
		return new $class($this, $name);
	}
	// Univerzální továrna
	return parent::createComponent($name);
}

?>

Co si o tom myslíte?

jasir
Člen | 746
+
0
-

Používám něco podobného. Myslím, že tak jak jsi to napsal je to ok, ale do frameworku jako takového ne. Je to příliš magické.

Patrik Votoček
Člen | 2221
+
0
-

Tohle je OK dokud nepoužíváš namespace pak už je to hodne WTF…

Petr Motejlek
Člen | 293
+
0
-

Je to hezké, když si to představíš ve stavu, kdy máš jednu komponentu, jednu třídu a jednu instanci té třídy. Analogie s menu je docela trefná.

Pak jsou ale chvíle, kdy se ti už nehodí, aby bylo jméno komponenty stejné jako jméno třídy, například třída ProductListRenderer – typický výpis produktů v nějakém internetovém obchodě. Už se mi párkrát stalo, že jsem v jistých případech potřeboval mít na jedné stránce víc výpisů, sice to pokaždé byla jedna třída, jen každá instance měla jiný datasource, ale ty komponenty už se musely jmenovat jinak.

Já jsem si nakonec zvykl nedělat třídy Menu, ale raději MenuRenderer (občas i MenuControl, ale to se mi moc nelíbí ;)), továrničky dělám pořád a nevšiml jsem si, že by mě to nějak výrazně zdržovalo, spíš to přináší přehlednost.