Hirdetés

Hozzászólok Aktív témák

  • modder

    aktív tag

    Ezekkel az egyedi szépnek tűnő megoldásokkal az a baj, hogy ha átviszed a kódot egy másik kontextusba, ahol nem a saját autoloadered van használva, a statikus inicializáló blokk nem fog lefutni, ellenben a "csúnya" megoldással, ahol mindig lefut.

    De ha nem tetszik a csúnya megoldás, akkor keringenek még olyan javaslatok a neten, hogy privát konstruktor és factory metódus használata új objektum létrehozására, ahol a factory metódusban elrejtheted a statikus inicializáló részt.

  • Athlon64+

    senior tag

    LOGOUT blog

    Azzal nem lenne senki sem kisegítve, akinek ilyenre van szüksége, hiszen static dolgok alapvetően nem öröklődnek (late static binding van PHP-ban, de ájjáj), no persze private ctor mellett meg aztán semmit sem tehetsz öröklődés terén.

  • modder

    aktív tag

    "hiszen static dolgok alapvetően nem öröklődnek"
    Eddig úgy tudtam, hogy a statikus metódusokat ugyanúgy megörökli a gyerek osztály.

    Ha új statikus konstruktort akarsz a származtatott osztálynak, felülírhatod a régi metódust. Esetleg a call_user_func late bindingot használ?

    A privát konstruktor lehet protected is, az részletkérdés, attól függ, hogy az osztályt öröklésre tervezed-e vagy sem.

  • Athlon64+

    senior tag

    LOGOUT blog

    Igen, elérhető minden a gyerekosztályon keresztül is, de minden elég kretén módon történik a self:: és a static:: körül (szerintem csak problémát jelent ez a két kulcsszó ilyen használatban), érdemesebb talán úgy tekinteni a static elemekre, hogy adott osztályhoz tartoznak, az adott osztályon keresztül kell őket meghívni, ha épp metódusról van szó, és el kell felejteni, hogy a gyerekben is elérhetőek.

    A call_user_func() kérdés egészen helyén való bizonyos értelemben: ha az aktuális osztályban nincs static function __static, akkor meghívja a szülő (fenti gondolatból következően) megfelelő nevű metódusát, ami probléma lehet, viszont a method_exists() megfogja (nem látja a szülőét!), így nem lesz kétszer vagy töbször meghívva a szülő static ctor-ja.
    Late static binding-et nem használ, csak épp ki tudja szolgálni, mint egy pár más megoldás is, hiszen forward-olja a hívó osztályt (nyilván a szülő osztályon keresztülit nem).

    Factory method-oknak a valamennyire is zárt konstruktorral megvan az a problémájuk, hogy nehéz tesztelni őket. Azonos autoloader-t használva nem lehet semmi ilyen jellegű problémája a fejlesztőnek. (Azt persze nem szabad elfelejteni, hogy a bevezetett static ctor-ba sem kerülhet olyan logika, ami csak ott létezik, máshogyan elérhetetlen.)

  • modder

    aktív tag

    A "late static binding" eléggé erőltetettnek és kerülendőnek tűnik, főleg, hogy alapból úgy működnek a statikus metódusok PHPban, ahogy elvárható tőlük más programnyelvből kiindulva.

    Én így látom:
    Autoloaderes megoldás
    Kényelmes az osztályok létrehozásakor, viszont method_exists() miatt nem fogja a szülő __static()-ját meghívni, ezért körültekintőnek kell lenni származtatásnál. Az osztály újrafelhasználásakor be kell regisztrálni egy külön autoloadert úgy, hogy az kompatibilis legyen a korábban regisztrált autoloaderekkel: azok ne találják meg az osztályt.

    Statikus factory metódusok
    Hordozható, de oda kell figyelni származtatásnál, hogy a factory metódusokat felülírjuk, ha több is van, ez kényelmetlen, és későbbi fejlesztő elfelejtheti. (igazából ezzel az erővel már a konstruktorban is meg lehetne hívni az statikus inicializáló metódust)

    PHP class fájl végén hívott init
    Legmegszokottabb megoldás, nem kötelező származtatott osztálynál meghívni vagy felülírni.

    Érdekes megoldás, de amennyiben az osztály helyes működése függ a loadertől, maximum keretrendszerekben használnám. A statikus inicializáló blokkra egyébként is ritkán van szükség, kérdéses, megéri-e egy ilyen függőséget tenni az osztályokba.

    [ Szerkesztve ]

  • Athlon64+

    senior tag

    LOGOUT blog

    Semmi baj nincs belőle, hogy a szülő static ctor-ját nem hívja meg, majd meghívódik akkor, amikor a szülőt behúzza a PHP maga alá az adott loader-rel.
    Keretrendszerben alkalmazom ezt a cuccot, nyilván egy olyan modulnál, ami külön is életképes, nem igazán lehet használni.

    Factory method-októl nekem többnyire feláll a szőr a hátamon, de az még durvább lenne, ha egy instance létrehozásakor még el kellene látnom az osztály inicializálását, nekem ez a kettő nagyon külön áll.

    A fájl végén található Init hívásról mindig az jut eszembe, kb. minden gondolkodás nélkül kitörölném a "class-t bezáró kapcsos zárójel plusz új sor" szerkesztési elvemmel. :DDD

    Az a baj, hogy PHP-ban nem lehet semmihez sem kötni bizonyos elemek betöltését, C#-ban meg lehet oldani különböző Assembly-kre akasztható attribútumokkal, de itt meg semmi sincs.

Hozzászólok Aktív témák