Finální konstruktor PresenterComponent
- Ondřej Mirtes
- Člen | 1536
Ahoj,
lidi mají neustále problémy s tím, že přepisují konstruktor (např.
v potomku Controlu či Presenteru) a aplikace jim pak nefunguje (komponenta
nepřijímá signály, Presenter taky zlobí). Navrhuji tedy, aby byl
konstruktor v PresenterComponent nastaven jako finální, aby k těmto
situacím nedocházelo.
- pekelnik
- Člen | 462
Ondřej Mirtes napsal(a):
Ahoj,
lidi mají neustále problémy s tím, že přepisují konstruktor (např. v potomku Controlu či Presenteru) a aplikace jim pak nefunguje (komponenta nepřijímá signály, Presenter taky zlobí). Navrhuji tedy, aby byl konstruktor v PresenterComponent nastaven jako finální, aby k těmto situacím nedocházelo.
To je dobrý nápad – zároveň by to chtělo nějaký mechanismus jako init() nebo setup() automaticky volaný z konstruktoru. Defaultně prázdná metoda.
- Mikulas Dite
- Člen | 756
Souhlasím.
pekelnik napsal(a):
zároveň by to chtělo nějaký mechanismus jako init() nebo setup() automaticky volaný z konstruktoru. Defaultně prázdná metoda.
Ta už existuje, je to metoda startup()
;
- pekelnik
- Člen | 462
Mikulas Dite napsal(a):
Souhlasím.
pekelnik napsal(a):
zároveň by to chtělo nějaký mechanismus jako init() nebo setup() automaticky volaný z konstruktoru. Defaultně prázdná metoda.Ta už existuje, je to metoda
startup()
;
startup() je specifická metoda presenteru (určitá fáze zpracování požadavku)
zatímco setup by se volala v konstruktoru a byla by ve všech komponentách
já využívám konstruktory hojně především pro formuláře a další komponenty
- Majkl578
- Moderator | 1364
Podle mě je to takhle ideální. Špatné překrytí je čistě chyba programátora (z nepozornosti).
pekelnik napsal(a):
startup() je specifická metoda presenteru (určitá fáze zpracování požadavku)
zatímco setup by se volala v konstruktoru a byla by ve všech komponentách
To se mi ani trochu nelíbí. V tom by byl pěkný bordel.
- Ondřej Mirtes
- Člen | 1536
Nějaká metoda init() anebo přesunout startup() už do Controlu (s tím, že by si ho Presenter přepisoval).
- Honza Marek
- Člen | 1664
Ondřej Mirtes napsal(a):
Ahoj,
lidi mají neustále problémy s tím, že přepisují konstruktor (např. v potomku Controlu či Presenteru) a aplikace jim pak nefunguje (komponenta nepřijímá signály, Presenter taky zlobí). Navrhuji tedy, aby byl konstruktor v PresenterComponent nastaven jako finální, aby k těmto situacím nedocházelo.
Já bych byl asi pro, ale překvapuje mě, že s tímhle požadavkem přicházíš zrovna ty :)
- Ondřej Mirtes
- Člen | 1536
Já vím, to je fail :o) Naštěstí ta komponenta nemusí přijímat žádné signály, takže všechno funguje :o) Pokud se to do Nette dostane, holt udělám BC break a ten konstruktor zruším. Settery tam na ty věci jsou.
- v6ak
- Člen | 206
Přijde mi to trošku zvláštní. V Javě je toto vyřešené mnohem lépe, tam všechny konstruktory všech tříd (kromě java.lang.Object) musí volat buď jiný svůj konstruktor, nebo konstruktor předka. Dokonce je to AFAIK kontrolováno při tzv. verifikaci bytecode. (Jednou jsem na to nejspíš zapomněl a hned mi JVM nadávala.) Dokonce to asi musí proběhnout před prací s metodami rodiče, předáváním this apod. Toto by se tedy nestalo.
Celkově filozofie konstruktorů je IMHO taková, že každé třídě je houby po tom, jaké konstruktory mají potomci. Ať si třeba přijímají něco dalšího. Jen ať prvně inicializují rodičovskou třídu jejím konstruktorem a pak s ní pracují. (Protože předtím by to znamenalo práci s neinicializovanou třídou a tudíž nedefinovaný výsledek.)
Pravda, Presentery jsou trošku specifické tím, že jsou instanciovány nejspíš přes Reflection a tedy mají učitou pevnou strukturu API konstruktoru.
- Honza Marek
- Člen | 1664
U controlů už to mělo dávno být. Podle mě přepsaný konstruktor controlu je prasárna, pač se pak nedá spolehnout na standardní chování.
- Honza Kuchař
- Člen | 1662
Honza Marek napsal(a):
U controlů už to mělo dávno být. Podle mě přepsaný konstruktor controlu je prasárna, pač se pak nedá spolehnout na standardní chování.
Něco na tom bude. I přes to, že je to BC break, jsem pro.
- redhead
- Člen | 1313
A co na to jít cestou, kterou se vydal před nějakou dobou startup? Musí prostě volat svého předka. Prostě podobnou kontrolu toho, že programátor napsal parent::__contruct(). Pokud to tedy vyřeší problém, páč úplně nevím, v čem je zakopaný pes s nefunkčností signálů atd.. (pokud si dobře vybavuju, tak v nějaké topicu o tomhle, volal parent a stejně mu to nefungovalo, tak nevím)
- Honza Marek
- Člen | 1664
Jo a Datagrid taky přepisuje konstruktor. Dost divoce a moc nerozumim tomu proč.
- Honza Kuchař
- Člen | 1662
Honza Marek napsal(a):
Jo a Datagrid taky přepisuje konstruktor. Dost divoce a moc nerozumim tomu proč.
Je to kvůli obnovování stavu datagridu ze session
.
Editoval honzakuchar (5. 3. 2010 23:25)
- Honza Marek
- Člen | 1664
redhead napsal(a):
Dyť říkám – udělat to stejně jako u startupu.. Musí se volat předek. Tečka. „Interní“ konstruktor může plnit nějakou private proměnnou na TRUE a ta se bude kontrolovat ve startupu, pokud bude FALSE, vyhodí vyjímku, že se nevolá předek.
Předek nepředek, to je jedno. Pro mě je důležitější, abych byl schopen komponentu připojit k nadkomponentě takhle:
new Komponenta($this, $name);
To ta tvoje kontrola vůbec neřeší.
- redhead
- Člen | 1313
Tak to už je věc toho člověka co bude chtít posílat do konstruktoru. Pokud nebude připojená přes konstruktor, udělá si to nette samo (pokud použiješ továrničku samozřejmě).
Co když chci, aby si to nette dělalo samo a do konstruktoru posílal jen svoje určitý parametry? Tak to tak udělám. Pak už je problém, že pokud nepoužiju továrničku, laděnka bude řvát, že není připojená k jiné komponentě, ale to už je chyba programátora. Šlo jen o to, jak zabránit programátorům udělat chybu nevolání předka. Když ho volat nebudu, žádná chyba řvát nebude a pak si někdo myslí, že komponenta funguje jak má i když nefunguje (signály).
- v6ak
- Člen | 206
Tady je hlavně IMHO velký rozdíl mezi Presenterem a komponentou. U Presenteru chceme, aby ten konstruktor měl nějaké rozhraní (trošku zvláštní přístup, ale asi jsem ještě neviděl lepší řešení) a použití final by… bylo možná trošku zvláštní a mělo mírné vedlejší následky, ale zabralo by to.
Obecné kompomnenty si ale instanciujeme sami, takže tady to nedává smysl. Konkrétní komponenta může chtít pro vytvoření vědět něco navíc.
Způsob zabránění (nebo spíše varování) nevolání parent konstruktoru jsem tu výše navrhoval a mohl by takto fungovat pro všechny třídy obecně. To je IMHO společné pro celé OOP, nejen pro Presenter a Component.
- Honza Marek
- Člen | 1664
Tak jsem v Griditu taky musel zrušit konstruktoru parametry. Když jsem je tam nechal a připojoval datagrid hned, tak blblo loadState. Celý strom komponent datagridu se totiž nepřipojil k presenteru najednou, ale postupně, a to dělalo neplechu.