sandbox: nette + dibi + model loader

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

EDIT: Jak se můžete dočíst v tomto vláknu, modelLoader je antipattern (více viz níže). grogy tedy upravil původní sandbox a nyní si tedy můžete stáhnout funkční sandbox nette + dibi bez modelLoaderu. Na githubu je také původní sandbox (nette+dibi+modelLoader)

Ahoj, různě po fóru se válí spousta užitečných kousků kódu, ze kterých jsem si dal dohromady funkční sandbox, který používá dibi a modelLoader.

K modelům se z presenteru přistupuje pomocí

<?php $this->getModel("SampleName")->sampleMethod($arg); ?>

Stejným způsobem je možné pracovat s modelem z jiného modelu.

Verze knihoven: Nette 2.0.7, dibi 2.0.1.

Ke stažení je na https://github.com/…-modelLoader.

Pokud to někomu ušetří práci, tak budu jenom rád :-). Zároveň pokud si někdo všimnete nějakých nesmyslů, dejte mi prosím vědět. Díky.

Editoval xlilien (31. 12. 2012 19:48)

Filip Procházka
Moderator | 4668
+
0
-

Mám chuť ti to smazat. ModelLoader je považován za odpornou zastaralou praktiku, porušující všechny pravidla pro psaní čistého kódu.

Tomáš Votruba
Moderator | 1114
+
0
-

Ahoj,

načítání přes modelLoader je zastaralé a porušuje zákonitosti dependecy injection. Od Nette 2.0.5 je navíc k dispozici metoda inject, která způsob předávaných služeb (modelů) v presenterech ještě více zpřehledňuje. Od verze 2.1-dev je možno ji využít i pro továrničky.

Koukni na čerstvě aktualizovaný návod na načítání modelů právě pomocí DI Containeru a inject.

Sandbox využívající jak aktuální verzi Nette, tak dibi, by byl jistě fajn.

Editoval Schmutzka (28. 12. 2012 21:23)

grogy
Člen | 147
+
0
-

Pokud bude xlilien souhlasit s úpravou sandboxu na rozumnější formu, tak rád pomůžu.

První věci co jsem si všiml:

  1. Předání závislostí do modelů
  2. Předávání závislostí do presenterů
  3. Zbavení se contextu

(Chci se odvděčit komunitě kolem Nette za skvělou, ovšem na přispívání do nette/nette se zatím necítím)

Tomáš Votruba
Moderator | 1114
+
0
-

@grogy: Při nejmenším můžeš poslat pull request, při nejlepším z toho na konci uděláme návod do Planette. :)

Jan Tvrdík
Nette guru | 2595
+
0
-

Filip Procházka wrote: ModelLoader je považován za odpornou zastaralou praktiku, porušující všechny pravidla pro psaní čistého kódu.

Mýlíš se, můj drahý HosipLane. Neporušuje to zdaleka všechna pravidla pro psaní čistého kódu, spíš tak jedno či dvě. Není to odporná praktika, ale funkční přístup nasazený v mnoha aplikacích (po celém světe, napříč programovacími jazyky) disponující určitými nedostatky kvůli kterým je dnes často (ne vždy!) preferováno DI. (Nedíval jsem se na konkrétní implementaci.)

xlilien
Člen | 27
+
0
-

Filip Procházka napsal(a):

Mám chuť ti to smazat.

To by možná byla škoda – jen ať ostatní vidí, jak se to nemá dělat :-) !

Schmutzka napsal(a):

Ahoj,

načítání přes modelLoader je zastaralé a porušuje zákonitosti dependecy injection. Od Nette 2.0.5 je navíc k dispozici metoda inject, která způsob předávaných služeb (modelů) v presenterech ještě více zpřehledňuje. Od verze 2.1-dev je možno ji využít i pro továrničky.

Koukni na čerstvě aktualizovaný návod na načítání modelů právě pomocí DI Containeru a inject.

Díky za linky, četl jsem dependecy injection, metoda inject a načítání modelů pomocí DI Containeru a inject a bohužel jsem z toho nevyčetl, jak používat modely, aniž bych je všechny ručně musel registrovat v configu. Jde to?

Zkusím si projít ještě zbytek odkazů a pročíst to znovu, třeba na něco přijdu.

grogy napsal(a):

Pokud bude xlilien souhlasit s úpravou sandboxu na rozumnější formu, tak rád pomůžu.

xlilien rozhodně souhlasit bude, šel s kůží na trh proto, aby se někam posunul :-).

Díky všem za reakce!

Filip Procházka
Moderator | 4668
+
0
-

Jan Tvrdík napsal(a):

Není to odporná praktika, ale funkční přístup nasazený v mnoha aplikacích (po celém světe, napříč programovacími jazyky) disponující určitými nedostatky kvůli kterým je dnes často (ne vždy!) preferováno DI.

Mám pochopení pro service locator v presenterech. Nemám pochopení pro service locator v modelech a už vůbec nechápu, proč ho hájíš.

xlilien napsal(a):

bohužel jsem z toho nevyčetl, jak používat modely, aniž bych je všechny ručně musel registrovat v configu. Jde to?

Ano jde, pokud si napíšeš něco, co ti je všechny zaregistruje. Ale nedělej to, je to odporná magie, která vede k problémům. Prostě je všechny vyjmenuj – ano, ručně!

Jako bonus tvoje implementace by mohla být horší už jen pokud bys to celé měl statické.

  1. předáváš úplně všem třídám bez rozdílu DI Container a degraduješ ho tím na podřadný service locator
  2. vždy vracíš novou instanci „modelu“

Dál to nemám chuť studovat.


jako bonus hračka na usnadnění předávání závislostí do presenteru

Jan Tvrdík
Nette guru | 2595
+
0
-

Filip Procházka wrote: Mám pochopení pro service locator v presenterech. Nemám pochopení pro service locator v modelech a už vůbec nechápu, proč ho hájíš.

Hájím ho proto, že nevěřím, že DI je svatým grálem. Věřím, že DI i service locator mají své výhody i nevýhody. Věřím, že service locator není ani zdaleka tak špatný, jak si někteří myslí. Věřím, že použití service locatoru je v mnoha případech v pořádku, někdy je to dokonce i lepší volba než DI.

Kdybys mu stručně poradil, že existuje lepší přístup, nechal bych to bez reakce, ale tys mu poskytl (IMHO) nepravdivou informaci a to já neodpouštím.

Filip Procházka
Moderator | 4668
+
0
-

Jak jsem již řekl. V určitých situacích je service locator šikovný. Do modelu však nepatří, ani kdyby byl 100× pozlacený.

Tomáš Votruba
Moderator | 1114
+
0
-

xlilien napsal(a):

bohužel jsem z toho nevyčetl, jak používat modely, aniž bych je všechny ručně musel registrovat v configu. Jde to?

Taky jsem s tím měl vnitřní (lenostní) problém, ale pak jsem zjistil, že je příjemné jedním pohledem zjistit (a vědět), které modely v aplikaci používám :). Navíc si to můžeš v případě velkého počtu modelů hodit do externí souboru, např. models.neon a ten jen includovat (pokud nechceš, aby ti to překáželo v configu).

grogy
Člen | 147
+
0
-

Schmutzka napsal(a):

Taky jsem s tím měl vnitřní (lenostní) problém…

Je to hodně pohodlné, např. pokud je potřeba modely měnit. Změníš na jednom místě (a navíc naprosto logicky v configu) a automaticky Ti funguje celá aplikace pod novým modelem (modely na stejném rozhraní).

xlilien
Člen | 27
+
0
-

Tak ještě jednou díky za rady. Smířil jsem se s tím, že modelLoader používat nebudu, jsem schopen si napsat inject metody.

Pořád mi ale není jasné, jak v rámci jednoho modelu pracovat s jiným modelem. Můžete mě nakopnout? Díky.

Filip Procházka
Moderator | 4668
+
0
-

V konstruktoru jej budeš standardně vyžadovat

class Foo extends Nette\Object
{
	private $bar;

	public function __construct(Bar $bar)
	{
		$this->bar = $bar;
	}

}
xlilien
Člen | 27
+
0
-

Filip Procházka napsal(a):

V konstruktoru jej budeš standardně vyžadovat

To mi mohlo dojít. Díky.

hrach
Člen | 1834
+
0
-

Njn, dalsi fail. Je naprosto standardni situace, je jeden model/manažer/fasáda vyžaduje více jiných manažerů, a že tato závislost je pouze v 1/n případů (metod). Ať už konstruktorem, tak injectem se vytvoří všechny instance manažerů. Tomu říkám optimalizační přístup. Přesně tady boduje ServisLocator, a přesně tady by se hodil Hosiplanuv autowire. Protože ten simuluje chování ServisLocatoru, ale přitom zachovává rozhraní plně podporují DI.

xlilien
Člen | 27
+
0
-

Díky grogy je nyní na githubu sandbox nette+dibi bez modelLoaderu.

grogy
Člen | 147
+
0
-

Dále bych se pokusil udělat toto:

  1. zprovoznit přihlašování, aby také pracovalo s dibi
  2. sjednotit styl (zatím jsem se snažil zachovat Tvůj @xlilien) na Nette code-styles?
  3. další nápady, co by bylo v dibi-examplu dobré uvést, aby to pomohlo začátečníkům?
Filip Procházka
Moderator | 4668
+
0
-

Mnohem lepší kluci! :)

Tomáš Votruba
Moderator | 1114
+
0
-

@grody: 3. Např. zmiňované použití modelu v jiném modelu, ale vidím problém v tom, že se musí naplnit i konstruktor BaseModelu (to je sice možné, ale nepohodlné, zejména má-li více prvků).

Taky bych zachoval BaseModel, zkus si vytvořit 5 různých modelů a do každého pěkně dostat findById().

@hrach: To zní moc dobře. Lze tedy nějak použít inject, resp. autowire service locator přímo na tyto modely?

Editoval Schmutzka (1. 1. 2013 10:21)