PHP - kis refaktorálás
Sziasztok!
Van egy iteratorom, amiben a next-et szeretném szebb formára alakítani:Ami történik:
Nekem nem állt össze fejben, hogy ebből hogy lehet tömörebb és érthetőbb kódot csinálni, az elnevezésekkel szintén gondban lennék, bármi ötlet ezzel kapcsolatban?
■ Van egy iteratorom, amiben a next-et szeretném szebb formára alakítani:
class TreeIterator {
public function next() {
if ($this->isBranch())
$this->addBranchIterator();
else
$this->stepCurrentIterator();
while ($this->hasIterator() && !$this->isIteratorValid()) {
$this->removeCurrentIterator();
$this->selectParentBranchIterator();
if ($this->hasIterator())
$this->stepCurrentIterator();
}
if ($this->hasIterator())
$this->updateVisitor();
}
//...
}
- ha az előző elem ág volt, akkor hozzáadjuk az iterátorát (és közben meghívjuk a rewind-ot rajta), ellenkező esetben léptetjük az aktuális iterátort a következő elemre
- ezek után teszteljük, hogy az aktuális iterátorunk valid e, szóval hogy létezik e rajta a következő elem (vagy ha rewind-olt iterátor-ról van szó, akkor létezik e első elem)
- ha nem létezik a következő elem, akkor töröljük az aktuális ág iterátorát, és átlépünk a szülő ág iterátorára, azt léptetjük a következő elemre, és megnézzük, hogy azon létezik e a következő elem, és így tovább, amíg egy olyan szülő ágat nem találunk, amin létezik a következő elem, vagy el nem fogynak az iterátorok
- ha létezik a következő elem (szóval nem fogytak el az iterátorok), akkor frissítjük a visitor-t (ez a bejárás adatait tárolja, egyelőre nem tudtam jobb nevet kitalálni neki)
Nekem nem állt össze fejben, hogy ebből hogy lehet tömörebb és érthetőbb kódot csinálni, az elnevezésekkel szintén gondban lennék, bármi ötlet ezzel kapcsolatban?
az elnevezésekkel szintén
Haha, imádom a trollkodást :D
Hogy on is legyek, szerintem
A while ciklusban picit furcsa, hogy kétszer ellenőrzöd, hogy $this->hasIterator(), azon talán lehetne spórolni valahogy.
Engem is ez zavar, de nem
Az a baja, hogy ennek igazából do-while-nak kéne lennie, mert először léptet, utána tesztel, de annak meg nem ajánlott a használata...
Az a baja, hogy ennek
Ja haverom egy programozós
Update:
Azt mondta, hogy Dijsktra szerint nem írunk hátultesztelőt, szerinte hülyeség, de betartja.
Köszönöm. Megnyugodtam.
Ja megnéztem, azzal sem lehet
Miért nem használsz
Semmivel nem nyújt többet,
- A teljes fa bejárása egy magasabb absztrakciós szintű probléma, mint 1-1 ág bejárása, a RecursiveIterator-ral viszont a teljes fa bejárását és az ágak bejárását is ugyanazzal az osztállyal csináltatod meg, szerintem ez gányolás.
- Más szemszögből nézve, ha akarsz egy olyat csinálni, hogy vegyes gyűjteményekből álló fa, és be akarsz vinni egy új gyűjteményt, akkor vért fogsz izzadni, mert ez egy struktúrált programozásra jellemző megoldás, nem pedig egy objektum orientáltra. Struktúráltban az új típust nehezebb létrehozni, objektum orientáltban meg az új metódust.
(Egyébként eddig boldog tudatlanságban éltem ezzel kapcsolatban, de ha felmerült volna, mint lehetőség, akkor is elvetettem volna.)Fa, részfa
Mi különbség van egy teljes fa bejárása és egy részfa bejárása között? Miért más absztrakciós szint, ha a kiinduló csúcs a gyökér elem, mint bármely más elem?
A teljes fához útvonal
Nem teljesen értem a
A RecursiveIterator-ból az Iterator rész lényegében a fában egy szint. Ezt bővítik ki a getChildren() és hasChildren() metódusok, amelyek minden szinten minden elemre meghívódnak (pontosabban a getChildren() csak akkor, ha a másik true-t ad vissza).
Ha neked a fában minden elemed önmagában is egy iterator, akkor meg két foreach-et egymásba ágyazol: a külső visszaadja az adott elemet (RecursiveIteratorIterator), a másik meg ezen végig iterál. Az ebben visszakapott elemek meg ugye lehetnek akármilyen típusúak, azonban ha ezt kihasználod és tényleg több minden lehet (polimorfizmus hiánya), akkor az már régen rossz.
De ha mondanál egy példát, akkor könnyebben megérteném a problémád.
Kérdés:A
A RecursiveIterator-ral hogyan jársz be egy fát (most maradjunk csak a tömbnél), és kéred le minden elemnél az aktuális mélységet és útvonalat?
Mondjuk szeretnék egy ilyen transzformációt:
RecursiveArrayIterator
Oké, meggyőztél,
Path-et célszerűbb így, ha eseménykezelőt akarsz betenni a szint csökkenéshez (mondjuk html záró taget vagy ilyesmit).
A témához kapcsolódva...
Viszont valamire kíváncsi lennék: van-e valami ok arra, hogy ha az ember egy fastruktúrát akar modellezni, akkor ennek egyes elemei ne objektumok legyenek (pl. PHP esetében, ahol nem érvényesül a "minden objektum" elv), hanem hash(???) vagy egyszerű tömb, elemi adatokból felépítve, ahogy az itt látható példában?
Ugyanis én elkövettem azt a merényletet, hogy létrehoztam egy osztályt, ami egy belső listában azonos osztályú objektumokat tárol, így egyetlen for ciklussal végig tudok lépkedni a teljes fán. (pythonban viszonylag egyszerű így iterátort/generátort készíteni)
Erre leginkább akkor van
Lehet, hogy félreértelek, de
(performancia szempontjából egyértelműen nem, de már többször le lettem ******, hogy ne akarjak előre optimalizálni :) )
Pl. esetemben semmi másra nincs szükség, mint a fájlok nevére, elérési útjára, illetve könyvtárak esetében a bennük tárolt fájlok listájára.
Végeredményben ezeket egy hash tömbben is tárolhatnám, kulcsként a nevet, értékként meg, ha könyvtárnév, akkor a benne található fájlok listáját, egyébként meg valami NULL értéket, esetleg mindenféle attribútumokat tárolhatnék, ha épp olyan a feladat.
Szóval azt próbálom megérteni, hogy hol a határ, ahol még érdemes elemi(???) adatokkal dolgozni és mikortól célszerű akár a performancia rovására is, objektumot készíteni ezekből.
Szóval azt próbálom
Én végső soron mindegyikből objektumot készítek, viszont ezt úgy teszem, hogy kezdetnek olyan fát adok meg, amit nagyon egyszerűen le tudok írni (nem feltétlen objektumokkal, lehet sima asszociatív tömbbel, vagy XML-el), és ezt transzformálom át objektumos formára automatikusan. Ezt az objektum fát is lehet szerializálni, és visszatölteni, szóval szerintem megoldható, hogy ne menjen mindez a performancia rovására. Gondolom ha van egy xml config fájl, azt te sem olvasod be és dolgozod fel minden alkalommal, amikor kiszolgálsz egy felhasználót...
:)
Az asszociatív tömbért meg külön köszönet... szombat óta törtem a fejem, hogy azt, amit a perlben hash-nek hívnak, minek hívják más helyeken. :)