Funkce které jsou společné pro několik presenterů

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

Zdravím všechny, mám jeden docela zásadní problém. Mám několik presenterů (každý vykresluje jinou část stránky) ale potřeboval bych v nich nějakým způsobem používat určité funkce, které získají určitá data (dejme tomu že třeba pro graf). Vykreslení je stejné, momentálně mám v několika presenterech stejnojmenou funkci, což není dobře. Dokážete mi poradit, do které složky, jaký soubor a kde a jak co dát, abych na to mohl odkázat? :)
Používám standardní sandbox, není nijak upraven, jediné co je v něm navíc je hodně presenterů a hodně složek šablon, nic víc. Jinak aktuálně volám funkci přes

$this->nazevFunkce(parametry)
Jan Mikeš
Člen | 771
+
+7
-

Záleží, co ta funkce dělá, počítá něco? Je v ní business logika? Vykresluje? Napadají mě 4 možnosti jak kód „uklidit“ s DRY v mysli:

  1. Společný abstract presenter, od kterého budou dědit
  2. Trait
  3. Přesunout kód do samostatné třídy, tu zaregistrovat jako službu a injectovat do presenterů
  4. Komponenta (v případě, že se jedná o část, která se vykresluje na více místech stejně)

Editoval Lexi (14. 10. 2016 10:09)

Webster.K
Člen | 212
+
0
-

Ta funkce přistupuje k databázi, ze které vybírá data a na základě parametrů počítá a vrací hodnoty, které v metodě renderNeco() přidávám do šablony přes $this->template->data

Jan Mikeš
Člen | 771
+
0
-

K tomu bych tedy doporučil vytvořit si samostatnou třídu, tu si v configu do sekce services zaregistruješ jako službu.
Do této třídy si přes konstruktor můžeš injectnout databázi.
V presenteru pak máš na výběr více možností, jak sem tu službu dostat, doporučil bych @inject metodu:

class MyPresenter {
	/** @var \App\My\Service @inject */
	public $myService;

	public function renderDefault($a, $b)
	{
		$this->template->data = $this->myService->calculateXY($a, $b);
	}
}

Více o DI a předávání závislostí se můžeš dočíst v dokumentaci

Editoval Lexi (14. 10. 2016 11:24)

Webster.K
Člen | 212
+
+1
-

Vypadá to, že to funguje, po pár šílených errorech jsem to rozchodil :) děkuji za rady

Svaťa Šimara
Člen | 98
+
+1
-

Lexi napsal(a):

Záleží, co ta funkce dělá, počítá něco? Je v ní business logika? Vykresluje? Napadají mě 4 možnosti jak kód „uklidit“ s DRY v mysli:

  1. Společný abstract presenter, od kterého budou dědit
  2. Trait
  3. Přesunout kód do samostatné třídy, tu zaregistrovat jako službu a injectovat do presenterů
  4. Komponenta (v případě, že se jedná o část, která se vykresluje na více místech stejně)

1 a 2) Rozhodně nedoporučuju, jde o zneužití dědičnosti.

3 a 4) To bude rozumný směr. 3 se bude navíc výborně testovat.

Lukes
Silver Partner | 68
+
0
-

Fafin napsal(a):

1 a 2) Rozhodně nedoporučuju, jde o zneužití dědičnosti.

3 a 4) To bude rozumný směr. 3 se bude navíc výborně testovat.

Proč by měla být traita zneužití dědičnosti? (Když teda pominu, že pro tento use case je rozhodně lepší samostatná služba.) Je to běžné u prototypovaných jazyků. Dnes se stejně rozdíly mezi prototypovanými a třídními stejně stírá, protože se to kombinuje u moderních jazyků, což PHP je.

Pokud jde o nějaké modifikace presenterů viz nějaké specialní odesílání odpovědí, či nějaké funkce na zpracování AJAXu, tak je to docela vhodné a šikovné. Lepší jak nějakej AbstractPresenter…

Editoval Lukes (17. 10. 2016 10:10)

Svaťa Šimara
Člen | 98
+
+1
-

Proč by měla být traita zneužití dědičnosti? (Když teda pominu, že pro tento use case je rozhodně lepší samostatná služba.)

Traity jsou v PHP náhradou za vícenásobnou dědičnost. V tomto případě autor potřebuje jednu funkcionalitu ve více presenterech. Využití dědičnosti (ať jednonásobné, či vícenásobné) je zneužitím dědičnosti. Dědičnost je vhodné používat pro specializaci zodpovědnosti, nikoliv ke znovupoužití kódu.

Je to běžné u prototypovaných jazyků. Dnes se stejně rozdíly mezi prototypovanými a třídními stejně stírá, protože se to kombinuje u moderních jazyků, což PHP je.

Pardon, zřejmě nerozuím. On se stírá rozdíl mechanismu vyhledávání metod v třídách oproti vyhledávání metod v dynamických prototypech? Jak?

Pokud jde o nějaké modifikace presenterů viz nějaké specialní odesílání odpovědí, či nějaké funkce na zpracování AJAXu, tak je to docela vhodné a šikovné. Lepší jak nějakej AbstractPresenter…

A co raději než trait použít třídu, která bude mít jasnou zodpovědnost za danou funkcionalitu? Co testování?

Lukes
Silver Partner | 68
+
0
-

Fafin napsal(a):

Proč by měla být traita zneužití dědičnosti? (Když teda pominu, že pro tento use case je rozhodně lepší samostatná služba.)

Traity jsou v PHP náhradou za vícenásobnou dědičnost. V tomto případě autor potřebuje jednu funkcionalitu ve více presenterech. Využití dědičnosti (ať jednonásobné, či vícenásobné) je zneužitím dědičnosti. Dědičnost je vhodné používat pro specializaci zodpovědnosti, nikoliv ke znovupoužití kódu.

Však já se s tebou nepřu, co je traita v PHP, mě jen trochu udivilo tvrzení, že „traita je zneužití dědičnosti“. Což jsi asi tak nemyslel (jak dále vysvětluješ a já s tebou souhlasím ;-), čili jestli sem tě urazil, tak se omlouvám.

Je to běžné u prototypovaných jazyků. Dnes se stejně rozdíly mezi prototypovanými a třídními stejně stírá, protože se to kombinuje u moderních jazyků, což PHP je.

Pardon, zřejmě nerozuím. On se stírá rozdíl mechanismu vyhledávání metod v třídách oproti vyhledávání metod v dynamických prototypech? Jak?

Já spíše myslel, že z historického hlediska prototypy nejsou standardní součástí třídních jazyků, ale objektově prototypovaných.

Pokud jde o nějaké modifikace presenterů viz nějaké specialní odesílání odpovědí, či nějaké funkce na zpracování AJAXu, tak je to docela vhodné a šikovné. Lepší jak nějakej AbstractPresenter…

A co raději než trait použít třídu, která bude mít jasnou zodpovědnost za danou funkcionalitu? Co testování?

No pokud píšu nějaké zpracování v presenteru stále a stále dokola viz flash, translate, redirect, či nějaký callback, tak na to psát nějakou třídu mě přijde zbytečné. Spíše myslím nějaké „shortcut“ metody. Co se týče testování nevidím problém v otestování traity, nebo ty ano? Samozřejmě, že se s tím dají napsat různé věci, které testovat je problematické, to se přít asi nebudu, ale záleží na konkrétním use case.

Editoval Lukes (17. 10. 2016 20:52)