Jak v Modelu A volat funkce z Modelu B
- Pepino
- Člen | 257
Zdravím, používam ModelLoader pro načítání modelů a chci se zeptat jak udělat následující.
class ModelA extends BaseModel {
function foo() {
$data = ????; // JAK ZAVOLAT FUNKCI ModelB::bar() ?
}
}
class ModelB extends BaseModel {
function bar() {
// TODO
}
}
Napadlo mě, že bych v ModelLoaderu předával jednotlivým modelům kromě DB připojení ještě instanci ModelLoaderu, ale nevím zda je to to správné ořechové.
Díky za odpověď! .)
- Bernard Williams
- Člen | 207
Nazdárek,
pokud jej chceš volat staticky, tak jej tak musíš nadefinovat:
public static function bar() {
// TODO
}
Pak půjde zavolat jako ModelB::bar()
.
Bernard
- Bernard Williams
- Člen | 207
A co třeba klasicky:
function foo() {
$model = New ModelB();
$data = $model->bar();
}
- Jan Endel
- Člen | 1016
Pokud pouzivas Tenhle modelLoader tak preci vidim ze v Base modelu se context v konstruktoru normalne plni, cili musi jit volat (pres getContext) a to se dela magii v Nette\Object nebo mi neco unika?
Nebo jak rika Bernard.
Editoval pilec (31. 7. 2011 15:01)
- Pepino
- Člen | 257
pilec napsal(a):
Pokud pouzivas Tenhle modelLoader tak preci vidim ze v Base modelu se context v konstruktoru normalne plni, cili musi jit volat (pres getContext) a to se dela magii v Nette\Object nebo mi neco unika?
Nebo jak rika Bernard.
Bernard říká nesmysl, jelikož, když udělám $modelB = new ModelB(); tak jak se asi v tom modelu dostanu k připojení k DB.. a připojovat se v každém modelu k db je blbost..
ModelLoader mám vlastní. V podstatě je každý modelLoader skoro stejný.. Ten na který jsi postnul link to řeší právě tak jak jsem napsal, že by to bylo možné.. Akorát místo instance modelLoaderu tam posílá celý container..
- studna
- Člen | 181
Obávám se, že nějaký jednoduchý ModelLoader ti tuto věc nevyřeší. Tady je lepší si model sestavit a nějak vložit do ModelLoader::$models a nebo přidat jako obyčejnou službu. Osobně ModelLoader moc nemusím.
Edit: Přes kontejner je to jednoduché, dle mého špatné řešení. ;)
Editoval studna (31. 7. 2011 15:40)
- studna
- Člen | 181
Pepino napsal(a):
Máš všechny modely registrované jako servis?
Dá se říct. Ještě předtím, než se aplikace spustí, si zaregistruju téměř všechny služby/modely.
Právě proto jsem založil tenhle topic abych našel lepší řešení :)
Nejlepší řešení je při vytváření instance předat objektu jen tolik služeb/vlastností, které potřebuje ke svému žití. :)
Editoval studna (31. 7. 2011 15:48)
- Nox
- Člen | 378
- předání ať už připojení nebo modelu
Úplně normálně – pomocí DI = ať si to doplní volající… a
volající může zas používat nějaký proxy objekt, jako třeba faktory, kde
Nette Container je takový mutant mezi Kontejnerem a Factory (ale z nějakýho
důvodu se jmenuje jen Container).
Takže se mrknout na možnosti – obecně buď konstruktorem nebo setterem
(doporučuje se kontruktor = povinná závislost, setter = volitelná
závislost…leda by toho v tom konstruktoru už bylo moc, ale pak by možná
sama třída byla moc bloated). A můžeš buď přímo nebo teda
v kontejneru
To co píše Bernard skutečně nebrat (tvorba cizí třídy – kde brát
její závislosti atd.)
- předávání kontejneru
Jestli předávat kontejner nebo konkrétní služby není úplně jasné, na jedné straně je kontejner pohodlný a nemusí být obří konstruktor, na druhé není jasné, co vlastně třída co ho příjmá potřebuje. Imho ani jeden není 100% správný, ale v současnosti předávám Factory třídám kontejner a doménovým třídám už jen konkrétní závislosti…ale říkám, ani jedno není na 100% ok (a to asi nebude nikdy, proto taky naštěstí programujem my a ne cvičené opice), předávání jen potřebného je trochu hezčí
- objekty a předávání v PHP
PHP nepracuje s objekty hodnotou, proměnná není ukazatel na jeho data
atd. Obsahuje pouze object ID a pokud máš nějaký objekt co umožňuje práci
s db a je připojený, pak ho můžeš předat 150ti objektům a stejně se nic
nepřipojí víckrát. Objekt je napříč systémem jedinečný, nezdvojí se,
pokud nezavoláš třeba manuálně clone
A taky si rozmyslet co vlastně tvoříš. To co je tady na foru nazývané jako Model – „model čeho??“ ⇒ normálně se to jmenuje „Repository“ … pokud potřebuješ u jedné Repository jinou, pak už asi mícháš Repository a Factory dohromady, což taky nebude ideál
Editoval Nox (31. 7. 2011 16:03)
- Nox
- Člen | 378
O tom mluví i studna, ano, tady se předává konkrétní využívaný objekt (a to že ho třída potřebuje sama sděluje pomocí parametru a jeho typehintu, obvykle je vhodný použít interface místo konkrétní třídy pokud existuje, jednodušeji se pak nahrazuje)
Editoval Nox (31. 7. 2011 16:17)
- studna
- Člen | 181
Takže posíláš konstruktoru jednotlivých modelů celý context?
Ne, předám jen to, co uvnitř modelu opravdu využiju.
- předávání kontejneru
Kontejner je fajn věc, to ano. Pokud potřebuji předávat více služeb pospolu, hodí se. Ale konkrétně u ModelLoaderu mi to nepříjde vhod, nasázet ještě další služby do kontejneru a předávat je všem načítaným modelům.