Strona 1 z 2 12 OstatniOstatni
Pokaż wyniki od 1 do 10 z 12
Like Tree4Likes

Wątek: Klasy - kilka sposobów na GET i SET

  1. #1
    Aktywny
    Dołączył
    Jul 2008
    Posty
    866

    Domyślnie Klasy - kilka sposobów na GET i SET

    Wiadomo, że jest wiele sposobów na GET i SET w klasach/obiektach. W dodatku wczoraj na shotuboxie miałem krótką rozmowę na ten temat. Zastanawia mnie tylko z którego jest najlepiej korzystać..

    Kiedyś używałem wszędzie public, teraz praktycznie zawsze używam private + wiele GETów.

    Kod php:
    $owoc->typ 'jablko'
    1. Public. Niby nic złego w tym nie ma, używając error_reporting można łatwo wyłapać literówki za pomocą E_NOTICE.
    Moim zdaniem bardzo przyjazne. Wadą jest brak możliwości wprowadzenia szybkich zmian, jednak to raczej nie będzie konieczne jeżeli odpowiednio się ogarnie kod.

    Kod php:
    $owoc->set('typ''jablko'); 
    2. "Magic methods". Problem w tym, że za pomocą tego mamy dostęp do wszystkich danych, więcej niż nam potrzeba.

    Kod php:
    $owoc->setTyp('jablko'); 
    3. Własnoręcznie napisane metody do każdego pola, którego potrzebujemy. Mamy całkowitą kontrolę nad każdą zmienną z osobna. Jednak nie jest to zbyt przyjazne i z tego co czytałem nie jest polecane, a jednak na tym ostatnio pracowałem.

    Naszła mnie ochota powrotu do public [nie w każdym przypadku, ale jednak]. Wiem, że wątek jest poruszany tysiące razy, przeczytałem dokładnie dwa tematy na stackoverflow, jednak interesuje mnie świeże podejście do tego tematu..

  2. #2
    Programista Awatar Aravorn
    Dołączył
    Apr 2011
    Posty
    343

    Domyślnie

    bezpośredni dostęp jak np.: $owoc->typ = 'jablko'; zdecydowanie złym podejściem jest - możliwość utraty innego pola na rzecz nowego przez proste nadpisanie itd.
    Ogólnie przeważnie programując (nie kodząc i się bawiąc) używa się indywidualnych getterów i setterów, można napisać jeden front-getter i front-setter.
    Metody magiczne pozwalają rozwiązać problem opisany na samym początku - sprawdzenie, czy podany element już istnieje i wywalenie błędu przy próbie nadpisania.
    to będzie działało tak samo jak: $owoc->set('typ', 'jablko');, tylko wiadomo prostszy dostęp będzie: $owoc->typ = 'jablko'; no ale to z kolei z powrotem otwiera pierwszą lukę bezpieczeństwa: nie zawsze pole ma mieć raz nadaną wartość, która nie może ulec zmianie.
    W przypadku getterów i setterów też możesz mieć nadpisywanie, ale da się to ograniczyć: metody sam w końcu definiujesz. W metodach magicznych z resztą też da się to spokojnie napisać
    Ogólnie pisząc dobrze, przemyślany kod nie ma za wiele takich sytuacji, tych pól publicznych na pewno nie będzie nie wiadomo ile (u mnie dla przykładu pojawiają się sporadycznie, na np. 5 klas będą 3-4 takie pola, w niektórych jednak więcej). Wszędzie robię gettery i settery indywidualne dla każdego z pól: podpowiedzi składni potem prawidłowe są, konkretne no i tak się uczyłem programować od lepszych ode mnie.
    Drikam likes this.

  3. #3
    Programista
    Dołączył
    Sep 2007
    Posty
    622

    Domyślnie

    Nie demonizowałbym bezpośredniego dostępu do zmiennych składowych obiektu. Używanie set/get pozwala na późniejszą zmianę źródła danych. Globalny set('cos', 'aaa') niespecjalnie ma sens - zamiast tego lepiej już użyć metod __set i __get.

    Osobiście powiedziałbym że obydwa rozwiązania (set/get dla każdej właściwości lub zwykłe zmienne składowe) mają swoje zastosowania i tutaj zdrowy rozsądek powinien raczej decydować o tym, którego podejścia należy użyć.
    Drikam likes this.
    http://orodlin.pl/ - Orodlin.pl Team Member
    http://blog.albitos.eu - Albi's Jogger - Z pamiętnika młodego programisty
    http://wsosnowski.pl - wizytówka

    Mam do wynajęcia miejsce na serwerze dedykowanym. Ktoś zainteresowany?

  4. #4
    Programista
    Dołączył
    Sep 2007
    Posty
    622

    Domyślnie

    Po dyskusji na ChatBox'ie proponuję następujące rozwiązanie:

    Kod php:
    <?php
    error_reporting
    (-1);
    class 
    IllegalVariableException extends LogicException
    {


    }
    class 
    MainObject
    {
        public function 
    __set($key$value)
        {
            throw new 
    IllegalVariableException('Illegal value write: '.$key.'='.$value);
        }


        public function 
    __get($key)
        {
            throw new 
    IllegalVariableException('Illegal value read: '.$key);
        }
    }


    class 
    Something extends MainObject
    {
        public 
    $a 'x';
        public 
    $b 'y';    
    }


    /*
    Dostep do zdefiniowanych zmiennych
    */
    $obj = new Something();


    /*
    Dostep do zdefiniowanych zmiennych
    */
    var_dump($obj->a);
    var_dump($obj->b);
    $obj->'t';
    var_dump($obj->a);


    /*
    Dostep do nieznanych zmiennych - rzucony zostanie wyjatek i od razu wiadomo, ze cos sie dzieje
    */
    try
    {
        
    var_dump($obj->c);
    }
    catch(
    IllegalVariableException $e)
    {
        
    var_dump($e);
    }


    try
    {
        
    $obj->'x';
    }
    catch(
    IllegalVariableException $e)
    {
        
    var_dump($e);
    }
    Każdy dostęp do niezdefiniowanych zmiennych zakończy się błędem. Jeżeli nadejdzie konieczność nadpisania domyślnego zachowania jakiejś właściwości, to w __set i __get dodajemy implementację tego przypadku.

    W tej chwili nie widzę wad takiego rozwiązania nad używaniem oddzielnych get/set dla każdej właściwości - jeżeli ktoś jakieś widzi to dajcie znać. Poprawię przykład o ich obsługę.
    Ostatnio edytowane przez Klaus Korner ; 29-06-2013 o 15:32
    Drikam likes this.
    http://orodlin.pl/ - Orodlin.pl Team Member
    http://blog.albitos.eu - Albi's Jogger - Z pamiętnika młodego programisty
    http://wsosnowski.pl - wizytówka

    Mam do wynajęcia miejsce na serwerze dedykowanym. Ktoś zainteresowany?

  5. #5
    Zasłużony Awatar karer
    Dołączył
    Apr 2008
    Posty
    2,554

    Domyślnie

    Ja mam inna koncepcje.

    Nie ma sensu ograniczania bezposredniego dostepu do zmiennych obiektu. Jedynie w przypadku pisania corowych fragmentow naszej aplikacji ma to wiekszy sens. Generalnie jesli piszemy cos niskopoziomowego to PRIVATE. Jesli piszemy cos do dziedziczenia to PROTECTED, a jesli piszemy cos uzytkowego to PUBLIC.

    PHP to nie jezyk w ktorym chcemy ograniczac dostep do danych. To raczej ma slozyc bezpieczenstwu naszych danych. Dla przykladu corowe fragmenty naszej aplikacji opierajace sie na private nie beda wadzily w zaden sposob swoim istnieniem, poniewaz beda wygladaly dla calego systemu na puste w srodku. Tak samo jesli uzywamy protected to mamy na celu chyba raczej implementacje w obiekcie ktory dziedziczy z niego, a nie w obiekcie ktory bedzie go widzial. tak wiec protected/private ma sens tylko jesli piszemy zautomatyzowany system obslugi danych w naszej aplikacji. Jesli wlasnie mamy inteligentne dziedziczenie albo tworzenie obiektow typu "$obj = new $klasa"...
    Drikam likes this.

  6. #6
    Programista
    Dołączył
    Sep 2007
    Posty
    622

    Domyślnie

    Obawiam się, że twój post nieco rozminął się z tematem. Cała rozmowa nie dotyczy ograniczania dostępu do zmiennych, a tego w jaki sposób uzyskiwać do nich dostęp (kiedy są już publiczne). Tworzenie metod get/set dla każdej zmiennej w obiekcie ma pewien cel - dzięki temu unikasz błędów wynikających z tego, że PHP jest językiem dynamicznie typowanym oraz zostawiasz sobie furtkę do zmiany źródła danych. Moje rozwiązanie wymusza jawne zdefiniowanie każdej zmiennej, której używamy. Dzięki temu mamy zalety tworzenia metod set/get (mniejsza szansa na błąd) bez konieczności tworzenia zbędnych metod. W związku z tym nie popełnisz takiego błędu:

    Kod php:
    <?php 
    class Player extends MainObject
    {
        public 
    $name '';
        public 
    $level 0;
    }
    $player = new Player();
    $player->anme 'Name'//wyleci wyjatek
    $player->level 12;
    ?>
    Co do public/private/protected - polecam poczytać na temat enkapsulacji i obiektowości, bo mam wrażenie że źle z nich korzystasz.
    http://orodlin.pl/ - Orodlin.pl Team Member
    http://blog.albitos.eu - Albi's Jogger - Z pamiętnika młodego programisty
    http://wsosnowski.pl - wizytówka

    Mam do wynajęcia miejsce na serwerze dedykowanym. Ktoś zainteresowany?

  7. #7
    Zarejestrowany
    Dołączył
    Aug 2011
    Posty
    32

    Domyślnie

    No niestety podejście języka php, ale również i javy, do właściwości jest krótko mówiąc brzydkie bo jeśli przyjmiemy że dla każdego pola mamy tworzyć dwie metody get i set,
    to w przypadku klas gdzie liczba pól jest >= 10 można zwariować. Niestety są przypadki, gdzie bez get, set się nie obejdzie :/ Druga sprawa, że jeśli te metody mają być tylko nakładką na pola, gdzie następuje zwrócenie bądź przypisanie wartości do pola prywatnego to nie mają wg mnie zupełnie sensu i lepiej (i szybciej ) używać zwykłych pól publicznych. Jednak należy pamiętać, aby trzymać się jednej koncepcji
    jak używamy get i set to do wszystkiego.

    Co do przykładu wyżej to nie ukazuje on wyższości używania get/set, a ułomność/cechę języków skryptowych ( chociaż taki błąd powinno zgłosić dobre ide ) , bo jak mówi programistyczne przysłowie :
    "Błędy w językach kompilowanych zgłasza kompilator, a skryptowych klient".

    Najlepsze podejście do właściwości jakie znam istnieje w języku C#, z zewnątrz zawsze wygląda jak zwykłe pole, a od środka implementujesz get/set tylko jeśli jest taka potrzeba, a gdy nie ma to nie implementujesz i ładne to i przyjemne też No ale C# to C#,a PHP to niestety tylko PHP.

  8. #8
    Zasłużony Awatar karer
    Dołączył
    Apr 2008
    Posty
    2,554

    Domyślnie

    Cała rozmowa nie dotyczy ograniczania dostępu do zmiennych, a tego w jaki sposób uzyskiwać do nich dostęp (kiedy są już publiczne).
    Klaus jestes pewien ze piszesz o programowaniu ktore cechuje umiejetnosc poslugiwania sie kodem i rozumienie go? To co ty przytoczyles to cos w rodzaju zgadywanki. To co ty podales rozwiazuja testy jednostkowe i glupota jest zabezpieczanie kodu w taki sposob. Wydaje mi sie ze to ty sie rozminales, bo przytaczasz argument "latwiejsze debugowanie" ktory nie pasuje tutaj wedlug mnie mimo wszystko.

    get/set ma sens tylko i wylacznie w przypadku, w ktorym dane ktore maja tam wyladowac musza byc w jakis sposob walidowane. Nie ma sensu tworzyc aliasow.
    Co do public/private/protected - polecam poczytać na temat enkapsulacji i obiektowości, bo mam wrażenie że źle z nich korzystasz.
    A ja mam wrazenie ze ludzie nie potrafia uzywac narzedzi ktore dostaja do reki. Obiektowosc to IDEOLOGIA/STYL a nie przestrzeganie konkretnych zasad. Na prawde nie widze sensu w czytaniu po raz kolejny tego samego. Nastepnym razem jak napiszesz cos takiego, to zastanow sie czy nie uczysz ojca dzieci robic...
    Najlepsze podejście do właściwości jakie znam istnieje w języku C#, z zewnątrz zawsze wygląda jak zwykłe pole, a od środka implementujesz get/set tylko jeśli jest taka potrzeba, a gdy nie ma to nie implementujesz i ładne to i przyjemne też No ale C# to C#,a PHP to niestety tylko PHP.
    Tutaj cie musze mile zaskoczyc bo w php takze cos takiego mozna osiagnac jesli mnie pamiec nie myli . Jest cos takiego jak przeciazenie operatorow w php.
    Ostatnio edytowane przez karer ; 30-06-2013 o 21:45

  9. #9
    Programista
    Dołączył
    Sep 2007
    Posty
    622

    Domyślnie

    Akurat kwestia debugowania to tylko jedna strona medalu - tak jak napisał damianostre - akurat ten problem powinien zostać wykryty przez dobre IDE. Jednak przy pracy w większym zespole czasami chcielibyśmy wymusić na zespole nieco pomyślunku podczas korzystania ze zmiennych składowych. I to nadal nie jest jedyny argument za tego typu rozwiązaniem. To, że czegoś nie używa reszta programistów nie oznacza, że rozwiązanie jest złe. Dlatego chciałem je tutaj przedstawić. Jak do tej pory nie otrzymałem żadnej konstruktywnej krytyki z twojej strony.

    Testy jednostkowe służą do kompletnie innych celów, a zabezpieczanie kodu przed błędami w jakikolwiek sposób ciężko nazwać głupotą (no, może poza ręcznym tworzeniem 20 metod set/get dla każdej zmiennej składowej).
    get/set ma sens tylko i wylacznie w przypadku, w ktorym dane ktore maja tam wyladowac musza byc w jakis sposob walidowane. Nie ma sensu tworzyc aliasow.
    I tutaj nie mogę się z Tobą zgodzić. Akurat walidowanie typów (a nie danych) nie jest jedynym argumentem za użyciem metody składowej opakowanej w metody set/get. Poczytaj na temat enkapsulacji i hermetyzacji.
    A ja mam wrazenie ze ludzie nie potrafia uzywac narzedzi ktore dostaja do reki. Obiektowosc to IDEOLOGIA/STYL a nie przestrzeganie konkretnych zasad. Na prawde nie widze sensu w czytaniu po raz kolejny tego samego.

    Akurat mój kod jest dosyć mocno sprzeczny z ideologią programowania obiektowego. Zwłaszcza biorąc pod uwagę kwestie hermetyzacji. Cały sens mojego kodu polega na tym, żeby tam gdzie ma to sens nie tworzyć setki metod set/get, a zostawić zwykłe zmienne składowe (bez utraty możliwości które te metody dają). Mam wrażenie, że zamiast przeczytać moje posty ze zrozumieniem, postanowiłeś napisać że jesteś zmęczony czytaniem ciągle tego samego.
    Najlepsze podejście do właściwości jakie znam istnieje w języku C#, z zewnątrz zawsze wygląda jak zwykłe pole, a od środka implementujesz get/set tylko jeśli jest taka potrzeba, a gdy nie ma to nie implementujesz i ładne to i przyjemne też No ale C# to C#,a PHP to niestety tylko PHP.
    Tutaj cie musze mile zaskoczyc bo w php takze cos takiego mozna osiagnac jesli mnie pamiec nie myli . Jest cos takiego jak przeciazenie operatorow w php.
    Przeciążanie operatorów ma się nijak do właściwości z C#. PHP co prawda udostępnie __get i __set (z których korzystam w moim kodzie z poprzedniego posta), ale jest to biedne rozwiązanie i tworzy więcej problemów niż ich rozwiązuje.
    Nastepnym razem jak napiszesz cos takiego, to zastanow sie czy nie uczysz ojca dzieci robic.

    Chciałem coś napisać na temat tego fragmentu twojej wypowiedzi, ale ograniczę się jedynie do tego zdania... Ręce opadają.
    http://orodlin.pl/ - Orodlin.pl Team Member
    http://blog.albitos.eu - Albi's Jogger - Z pamiętnika młodego programisty
    http://wsosnowski.pl - wizytówka

    Mam do wynajęcia miejsce na serwerze dedykowanym. Ktoś zainteresowany?

  10. #10
    Zasłużony Awatar karer
    Dołączył
    Apr 2008
    Posty
    2,554

    Domyślnie

    Akurat mój kod jest dosyć mocno sprzeczny z ideologią programowania obiektowego. Zwłaszcza biorąc pod uwagę kwestie hermetyzacji.
    Caly czas staram sie powiedziec ze programowanie obiektowe to IDEOLOGIA a nie zbior zasad. Ideologia mowi nam "rob to jak uwazasz, ale nie zapominaj o xxx". Ja na prawde nie widze sensu w przeroscie formy nad trescia ktora w tym wypadku staje sie oczywista.

    Stosowanie get/set ze wzgledu na typy w PHP to idiotyzm albo co najmniej ostra pomylka. Php jest jezykiem w ktorym wszystko dzieje sie dynamicznie i to jest jego ZALETA. Jaki jest sens na sile robienia z niego c++ albo innego jezyka. Wogole jaki jest sens porownywania tych jezykow ze soba w danym aspekcie? Tak samo nie potrafie powiedziec co jest lepsze "kwadrat czy kolo".

    Zamiast na sile w php szukac defektow potraktuj to jako ficzery. Jezyk jest bardzo dojrzaly i gdyby byl sens uzywania wszedzie to by tak tworcy jezyka to zaprojektowali. Nie szukaj dziury w calym. Pogrzebiesz kiedys w paru wiekszych projektach i zobaczysz ze ta cala teoria o hermetyzacji i marazmie nie ma najmniejszego przelozenia w zycie codzienne, bo liczy sie to, zeby aplikacja byla zrozumiala i prosta w rozwijaniu. Ideologia to sposob myslenia, ale nie zbior zasad. Mozna pisac aplikacje strukturalnie wedlug ideologii obiektowej co nieraz juz widzialem na wlasne oczy i to DZIALA.

Strona 1 z 2 12 OstatniOstatni

Informacje o wątku

Użytkownicy przeglądający ten wątek

Aktualnie 1 użytkownik(ów) przegląda ten wątek. (0 zarejestrowany(ch) oraz 1 gości)

Podobne wątki

  1. Brak klasy PDO
    Przez Drikam w dziale PHP / MySql
    Odpowiedzi: 9
    Ostatni post / autor: 01-09-2009, 06:37
  2. [Php] Klasy w grach via www
    Przez Helid w dziale PHP / MySql
    Odpowiedzi: 4
    Ostatni post / autor: 04-03-2008, 18:37
  3. [Php] Klasy
    Przez Vielta w dziale PHP / MySql
    Odpowiedzi: 4
    Ostatni post / autor: 18-12-2007, 16:52

Zakładki

Uprawnienia umieszczania postów

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •