Autor Zpráva
4ever
Profil
Mám dotaz jak resetovat všechny vlastnosti objektu, jako by byl objekt čerstvě vytvořený. Mám tuto třídu:

class Properties_class {
 public $e;
 public $c;
 public function __construct() {
  $this->c = New Condition_class();
  $this->e = New Effect_class();
 }
} 

A pak cyklus, na jehož začátku je vždy toto:
$this->p = new Properties_class();

Navíc teď už vím, že bych to mohl udělat jinak:

      $this->p = new stdClass; // reset all properties
      $this->p->e = new Properties_class();; 
      $this->p->c = new Properties_class();;

Ale nevím, který způsob je lepší (ten druhý je přeci jen na tři řádky, ale je přehlednější) nebo jestli se resetování neprovádí úplně jinak.
Majkl578
Profil
Znovu ho (ten objekt) vytvořit, to je asi to nejsprávnější řešení.
Mastodont
Profil
Nebo můžeš mít metodu Init, která nastaví počáteční hodnoty, a tu volat v konstruktoru a dle potřeby.
Crusher
Profil
4ever:
V podstate pouzivam to co napsal Mastodont, jen opacne.

Konstruktor pripravi cely objekt, to je i odpoved na tvou druhou otazku - celou inicializaci proved v konstruktoru, v kodu muzes snadno opomenout volani
$mujObjekt->p->e = new Properties_class();
a nebude tudiz obsahem objektu.

Vetsinou hned pod konstruktor si ja pridavam metodu "reDim()" (zvyk z dob davno minulych :-D) a tato dela jedinou vec. Znovu zavola
$this->__construct();
a tim mi cely objekt znovu pripravi ve vychozim stavu.
Nox
Profil
Ty jednopísmenné názvy fakt nevypadá dobře :) ... když už máš Condition_class a Properties_class atd. proč ne effect a condition?
(btw. proč to "_class"?)

A jinak souhlasím s Majkl578em že vytvořit nový objekt bývá lepší

Je otázka, čeho přesně chceš docílit
Majkl578
Profil
Crusher:
$this->__construct();
Něco takového se rozhodně nedá doporučit, je to špatné řešení. Správně bys, v případě opravdové potřeby, měl mít metodu (re-)inicializující objekt a tu volat z konstruktoru a příslušných míst. Mimochodem tvé řešení je nepoužitelné v případě parametrizovaných konstruktorů.

Pokud je třeba stav objektu resetovat úplně, pak by měl být ponechán zkáze a měl by být vytvořen nový objekt stejné třídy (samozřejmě vnějším kódem). Případně se to dá řešit návrhovým vzorem proxy.

Jmennou konvenci tříd/vlastností/metod raději nekomentuji, takové názvy jsou nesmyslné a odsuzují kód k záhubě.
4ever
Profil
Nox:
Jednopísmenné názvy se mi do toho kodu docela hodí, protože ty zápisy přístupů k objektům jsou dlouhý. Celý skript není o ničem jiném než o editování dvou skupin položek a to jsou efekty a podmínky. Když toto člověk ví, tak nemusí psát dlouhé názvy a šetří tím dost času i prostoru (lépe se to čte). Navíc mám zvykem vytvářet si ke složitějším skriptům nápovědu či průvodce. Třídu Effect_class a Condition_class tam mám proto, že mi to tak přijde přehlednější. Třídám prostě dávám delší názvy (objekty se většinou vytváří jen jednou), takže i z toho lze pochopit co daný objekt dělá.
Majkl578
Profil
4ever:
Jednopísmenné názvy se mi do toho kodu docela hodí, protože ty zápisy přístupů k objektům jsou dlouhý.
Nesmysl.

Když toto člověk ví
Neví. A u vhodně psaného kódu ani nepotřebuje.

lépe se to čte
Nečte.

Navíc mám zvykem vytvářet si ke složitějším skriptům nápovědu či průvodce.
Kdybys psal kód kvalitně, nemusel bys.

Třídám prostě dávám delší názvy
Logicky, to je běžná praxe. Noxova otázka ale byla proč nesmyslně používáš v názvu třídy _class.

Nezlob se na mě, ale já dostat k úpravám kód v podobném ražení jako je ten v [#1], zjistím si co má dělat, původní zahodím a napíšu jej raději znovu. A ještě bych pak měl noční můry, kde by se mi zjevovalo něco ve stylu (new HustodemonskaFeature_class())->e()[2]->w->u[1]['p']->q();.
Crusher
Profil
Majkl578:
Něco takového se rozhodně nedá doporučit, je to špatné řešení.
To je relativni. Pokud mam (ja) objekt, ktery konstruktor stvori jako prazdny objekt a k naplneni dochazi pres jeho metody (tak jak to mam ja) tak je to pro me plne dostacujici reseni. A osobne si myslim, ze na priklad, ktery uvedl na zacatku to bez problemu lze aplikovat. Samozrejme netrvam na tom, ze je to nejspravnejsi reseni pro vsechny :-).
Asi jedine nejspravnejsi je opravdu pouzit destruktor a cely objekt definovat znovu.

PS: pokud bych deklaroval objekt s parametrizovanym konstruktorem, tak bych urcite volil destrukci a novy objekt
Ugo
Profil
Majkl578:
Není pravda že uvedený pojmenování je nějak špatný, musís se jenom přenést přes to, že existují skripty kam nikdo jiný než původní uator nesáhne a většinou na ně sáhne přesně jednou při tvorbě. Pokud víš že e=effect tak to tak prostě čteš protože to máš v hlavě - nevidíš e, ale effect. Je to normální zkratka jako OOP, MVC, UI ... jenom tyhle jsou v podvědomí většího množství lidí, ale rozdíl tam neni.

Je faktem, že po delěí pauze a následný úpravě už prostě nevíš na první pohled co to znamenalo, tak u půlky si vzpomeneš hned a tu druhou půlku chvíli budeš luštit, ale když k tomu máš - a víš kde jí najít - nápovědu, tak to je chvilka jednoho klepnutí na čelo a vzdychu Ahááá.

To samé platí i o $this->__construct();

Samozřejmě to platí jen pro tvorbu kde se k tomu nikdy nedostane další nezasvěcená osoba která v tom vidí jenom jiný zkratky - WTF, OMG. Ale v případě vlastní tvorby pro sebe žádná konvence neexistuje, je lepší jí dodržovat protože se ti dostane pod kůži a líp s eti pak dělaj kódy pro oči jiných, ale neni to špatný.
4ever
Profil
Crusher:
$mujObjekt->p->e = new Properties_class();
>
a nebude tudiz obsahem objektu.
>
Vetsinou hned pod konstruktor si ja pridavam metodu "reDim()" (zvyk z dob davno minulych :-D) a tato dela jedinou vec. Znovu zavola
>
$this->__construct();
>
$this->__construct();
>
a tim mi cely objekt znovu pripravi ve vychozim stavu.

Tu metodu reDim() bych měl dát pod třídu Properties_class?
A pak to volat $mujObjekt->p->e->redim()?

Mě jen přijde, že pokud dám do konstruktoru Properties_class $this->__construct(); tak se by se to mělo zacyklit, protože by se pořád volal konstruktor.
Nox
Profil
Ugo:
kam nikdo jiný než původní uator nesáhne
A hle - jak málo stačí a už to není pravda. Autor se bude chtít na něco zeptat, nebo se bude chtít podělit s komunitou, atd. ... a rázem to mají chápat i jiní.

Když řešitelům nabídne nějakou hrůzu*, rázem oni musí trávit čas dešifrováním WTF anebo autor musí vynaložit mnohem větší úsilí u vysvětlení, než by vynaložil, kdyby to udělal hned pořádně.

To jedno klepnutí na čelo - je to asi individuální, u něčeho malého ano, ale u větších projektů s několika knihovnami a spoustou propojených objektů a systémů objektů už si to tak lehce představit nedovedu.

Zní to náročně, ale - zkuste si prostě někdy kus kódu napsat jakože řádně, třeba až moc ... pak uvidíme, přijde mi že to není tak hrozné, jak se zdá.

*) mluvím obecně, tento se ještě dá
Crusher
Profil
4ever:
Volanim $mujObjekt->reDim() pouze spustim metodu, ktera znovu inicializuje cely objekt tim, ze zavola $this->__construct(). A prave $this->__construct() obsahuje kompletne cely inicializacni kod objektu.
$this->__construct nemuze nikdy obsahovat volani $this->reDim() !!! Prvni duvod je ten, ze $this->reDim() neslouzi k inicializaci, ale k "re-inicializaci". Druhy duvod je zjevne zacykleni.

Mastodont pouziva prave opacny zpusob. Jeho inicializacni metoda je $this->Init(). Tato obsahuje vse potrebne pro vychozi nastaveni objektu. Poprve se vola tato metoda preve z konstruktoru a pozdeji, kdyz potrebuje re-inicializovat objekt, zavola jednoduche $mujObjekt->Init(); V jeho pripade je zase zrejme, ze uvnitr metody $this->Init() nikdy nemuze byt volani $this->__construct().

OK .. snad jsem ti to objasnil a "nezamotal" jeste o neco malinko vice.
Mastodont
Profil
Crusher:
Z hlediska programovací logiky je ale tvůj postup nesprávný, protože konstruktor má být z definice volán jen a jen jednou, a to při vytvoření objektu.
Crusher
Profil
Mastodont:
To nepopiram. A take nerikam, ze je to ten spravny nebo spatny. Ja ho takto pouzivam a jsem na nej tak zvykly. Tvuj zpusob je "cistejsi". Ale oba delaji v podstate to stejne :-)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0