sandbox: nette + dibi + model loader
- xlilien
- Člen | 27
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
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
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
Pokud bude xlilien souhlasit s úpravou sandboxu na rozumnější formu, tak rád pomůžu.
První věci co jsem si všiml:
- Předání závislostí do modelů
- Předávání závislostí do presenterů
- 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
@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
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
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
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é.
- předáváš úplně všem třídám bez rozdílu DI Container a degraduješ ho tím na podřadný service locator
- vždy vracíš novou instanci „modelu“
Dál to nemám chuť studovat.
- Seriál Jak na Dependency Injection – Zdroják
- Dependency Injection
- Konfigurace prostředí
- Inject Autowire
- Inject a DIC továrničky
A jako bonus hračka na usnadnění předávání závislostí do presenteru
- Jan Tvrdík
- Nette guru | 2595
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
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
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).
- Filip Procházka
- Moderator | 4668
V konstruktoru jej budeš standardně vyžadovat
class Foo extends Nette\Object
{
private $bar;
public function __construct(Bar $bar)
{
$this->bar = $bar;
}
}
- hrach
- Člen | 1838
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.
- Tomáš Votruba
- Moderator | 1114
@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)