Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Przydatnosc "getterow" i "setterow"
marcini82
post
Post #1





Grupa: Zarejestrowani
Postów: 190
Pomógł: 1
Dołączył: 20.05.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Witam!

Chcialbym poznac Wasza opinie na temat zwyczaju holdowanego przez czesc programistow, a mianowicie tworzenia metod typu
  1. <?php
  2. class testClass{
  3.  
  4. public $property;
  5.  
  6. getProperty(){
  7. return $this->property;
  8. }
  9.  
  10. setProperty($property){
  11. $this->property = $property; 
  12. }
  13. }
  14. ?>

Czy czesto to stosujecie i jakie macie z tego korzysci?
Oczywiscie to dosc eleganckie, zawsze mozna dopisac jakies warunki sprawdzajace poprawnosc danych itp.
Ale z drugiej strony pewnie rzadko te metody zostaja rozbudowane ponad schemat, ktory podalem wyzej (brak czasu i/lub checi), a czy bez dodatkowego kodu to ma sens? Napisanie tych funkcji to zmudna praca, mozna ja sobie czasem ulatwic za pomoca jakiegos generatora, ale tez nie dla kazdej wlasciwosci taka metoda jest sensowna. Poza tym, obecnosc wielu metod tego typu w klasie pogarsza troche czytelnosc jej kodu i odwraca uwage od metod naprawde istotnych.

Jesli mamy do czynienia z wazna klasa , ktora jest podstawa dla polowy aplikacji (albo bardzo uniwersalna, ktora bedziemy wielokrotnie uzywac w innych projektach), albo z jakimis kluczowymi wlasciwosciami, to mozna sie pokusic o metody ktore elegancko pobiora lub ustawia te wlasciowosci.
Ale czy zawsze jest sens sie w to bawic?

Ciekaw jestem Waszych opinii...
Go to the top of the page
+Quote Post
3 Stron V   1 2 3 >  
Start new topic
Odpowiedzi (1 - 19)
menic
post
Post #2





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


U mnie ilośc własciwosći publicznych jest znikoma. Tak wiec problem "nieczytelnosci" kodu tym spowodowany odpada. Natomiast własciwosci prywatne zmieniam bez tch wszystkich setterow.
IMHO zbyt dużo zmiennych w klasie świadczy o złym zaprojektowaniu klasy (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
Turgon
post
Post #3





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


PHP5 dostarcza __get i __set i jak przetestował Bastion są szybsze od settów i gettów (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Więc też ich używam ;] Z resztą menic: dużo zmiennych wcale nie świadczy o złym zaprojektowaniu, ale pewne klasy muszą je niestety mieć (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
mysz
post
Post #4





Grupa: Zarejestrowani
Postów: 81
Pomógł: 0
Dołączył: 26.08.2006
Skąd: Szczecin

Ostrzeżenie: (0%)
-----


Settery tego typu są brzydkie jak dla mnie. Zdecydowanie wolę wymienione przez Turgona magiczne właściwości __set i __get. Są znacznie czytelniejsze. Przykład kodu, jaki lubię stosować:
  1. <?php
  2. class Test {
  3. private $_data = array();
  4. public function __set($key, $value) {
  5. if (method_exists($this, '__check_' . $key)) {
  6. if (call_user_func_array(array($this, '__check_'.$key), $value)) {
  7. $this->_data[$key] = $value;
  8. } else {
  9. throw new Exception('nieprawidłowa wartość');
  10. }
  11. } else {
  12. $this->_data[$key] = $value;
  13. }
  14. }
  15. public function __get($key) {
  16. if (isset($this->_data[$key])) {
  17. return $this->_data[$key];
  18. } else {
  19. throw new Exception('brak właściwości');
  20. }
  21. }
  22. public function __tostring() {
  23. return sprintf('%s: %s', get_class($this), print_r($this->_data, 1));
  24. }
  25. public function __check_c($data) {
  26. return is_numeric($data);
  27. }
  28. }
  29. ?>


Użycie:
  1. <?php
  2. $test = new Test();
  3. $test->a = 'a';
  4. echo $test->a;
  5. echo '<br />';
  6. $test->b = 'b';
  7. echo $test->b;
  8. echo '<br />';
  9. $test->c = '123';
  10. echo $test->c;
  11. echo '<br />';
  12. try {
  13. $test->c = 'ass';
  14. echo $test->c;
  15. } catch (Exception $m) {
  16. print 'Jakiś problem: ' . $m->getMessage();
  17. }
  18. echo '<br />';
  19. echo $test;
  20. ?>


Oczywiśćie to powyżej to tylko bardzo prosty przykład, który wymaga dopracowania i rozbudowania, ale pokazuje jakie fajne możliwości tkwią w magicznych właściwościach :) Oraz, że zwykłe settery, w postaci znanej z Javy (setVar, getVar) są do tyłka... ;)
Go to the top of the page
+Quote Post
envp
post
Post #5





Grupa: Zarejestrowani
Postów: 359
Pomógł: 1
Dołączył: 16.04.2006
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Hah no świetnie, OOP polega na pisaniu jak najbardziej rozszezalnego kodu wiec lepiej sobie zrobic setZmienna() i getZmienna(), bo za miesiac okaze sie ze do class :: $zmienna ludziska wrzucaja wam śmiecie i potrzeba zrobić walidowanie danych przed zapisaem do zmienniej. Wlasnie przy samym zapisywaniu w klasie. Przyklad wyuskany, ale jak najbardziej pasuje do tego posta.
Go to the top of the page
+Quote Post
splatch
post
Post #6





Grupa: Zarejestrowani
Postów: 487
Pomógł: 7
Dołączył: 7.01.2004
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(mysz @ 16.03.2007, 22:17:05 ) *
Oczywiście to powyżej to tylko bardzo prosty przykład, który wymaga dopracowania i rozbudowania, ale pokazuje jakie fajne możliwości tkwią w magicznych właściwościach (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Oraz, że zwykłe settery, w postaci znanej z Javy (setVar, getVar) są do tyłka... (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Settery w Javie (jak i cała koncepcja JavaBeans) powstały na długo przed pojawieniem się PHP5 zatem krytykowanie Javy, za to, że nie ma metod "magicznych" mija się z celem.
Jest to przede wszystkim język statyczny, gdzie w chwili kompilacji powinna być znana już nazwa wykonywanej metody. Wywołania dynamiczne można zrealizować tylko przy pomocy Reflection API.
To nie jest PHP, gdzie możesz sobie bez jakichkolwiek konsekwencji skleić nazwę funkcji i zrobić $bar($foo) i $bar->$foo = $baz. Nie zapominaj o tym w swych ocenach. Na getterach możesz zbudować bardzo złożone mechanizmy - a klasy zaprojektowane w ten sposób bez problemu użyć do wyklikania interfejsu użytkownika w NetBeans (wskazane dodanie PropertyDescriptora). Nie musisz również bawić się z obserwatorami - wystarczy użyć PropertyChangeSupport i zaimplementować interfejs PropertyChangeListener w zależnym obiekcie.
W get/set z czasem coraz częściej pojawia się dodatkowy kod, od chociażby w celu poinformowania listenerów o zmianie w obiekcie ..
Pisząc w JSP możesz bez problemu korzystać z ${obj.property}, co w wyniku, po skompilowaniu do servletu da Ci obj.getProperty().

Jako ciekawostkę dodam, że w Javie 7 pojawią się prawdopodobnie bloki, w których będzie się deklarować property dostępne via get/set.
Go to the top of the page
+Quote Post
mysz
post
Post #7





Grupa: Zarejestrowani
Postów: 81
Pomógł: 0
Dołączył: 26.08.2006
Skąd: Szczecin

Ostrzeżenie: (0%)
-----


@splatch: pojęcie kontekstu wypowiedzi jest Ci obce? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) mało mnie interesuje Java, napomknąłem o niej tylko w kontekście tego, że to właśnie ten język upowszechnił taki zapis setterów i getterów. PHP5 daje znacznie wygodniejsze możliwości, których prosty i nierozbudowany przykład podałem. Nie mówiąc o tym jak wygodnie jest to rozwiązane w Pythonie czy C#, ale to już drobny szczegół...
Go to the top of the page
+Quote Post
mike
post
Post #8





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

Ostrzeżenie: (0%)
-----


Setery i getery pozwalają ba na bardzo szczegółową kontrolę dostępu do pół oraz metod obiektu. Są też najlepszym sposobem na walidację danych.

Dostęp za pomocą metod magicznych to głupota, nic nie daje a ogranicza w kilu rzeczach. Nie zrobisz kontroli dostępu walidacji i innych takich rzeczy.
A najgłupszą rzeczą jest to że takie rozwiązanie wymusza trzymanie wszystkich danych w tablicy. Chore, po to są pola, żeby każde trzymało coś innego a nie jedna wielka tablica, która jest rozwiązaniem wolnym i niewygodnym oraz nie możliwym d udokumentowania.
Go to the top of the page
+Quote Post
Turgon
post
Post #9





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


mike_mech, a kto tak powiedział ?
  1. <?php
  2. class example{
  3. protected $var = '';
  4.  
  5. public function __set($name,$value){
  6. if(!isset($this->{$name})){
  7. throw new Exception('Wartość '.$name.' nie istnieje, więc nie może być edytowalna!');
  8. }
  9. $this->{$name} = $value;
  10. }
  11.  
  12. public function __get($name){
  13. if(!isset($this->{$name})){
  14. throw new Exception('Wartość '.$name.' nie istnieje, więc nie może być pobierana!');
  15. }
  16. return $this->{$name};
  17. }
  18. }
  19. try{
  20.  
  21. $o = new example();
  22.  
  23. $o->var = 'Jakieś tam bzdury!';
  24.  
  25. echo $o->var;
  26.  
  27. $o->inna = 'Dupa'; 
  28. }
  29. catch(Exception $e){
  30. echo $e->getMessage();
  31. }
  32. ?>


Otrzymuje to co chciałem. Banalną kontrolą dostępu jest nie dodawanie setterów do zmiennych nie publicznych, które mają być nie edytowalne, a zmienne edytowalne jako publiczne. Też kto Ci zabronił używania obiektów kolekcji? Wolna amerykanka... Za to uwielbiam PHP.

EDIT:
Poprawiłem przykład. I dałem jeszcze prostszą kontrolę choć wymaga pewnych nawyków =] Np. dawania na początek zmiennym edytowalnym pustej wartości =]

Ten post edytował Turgon 17.03.2007, 09:17:15
Go to the top of the page
+Quote Post
mysz
post
Post #10





Grupa: Zarejestrowani
Postów: 81
Pomógł: 0
Dołączył: 26.08.2006
Skąd: Szczecin

Ostrzeżenie: (0%)
-----


@mike_mech: a mówiłem że przykład jest prosty i potrzeba go rozbudować...
Turgon podał jeden z przykładów jak można zrobić rozdzielenie pól, żeby nie trzymać wszystiego w tablicy. A tablicę taż można w prosty sposób udkokumentować, wystarczy chcieć. Już lepiej by było gdybyś napisał że wg Ciebie fajniejsze jest używanie metod set() i get(). Chyba że napiszesz coś konkretnego w kontekście anty.

Co do walidacji: przecież w moim przykładzie było pokazana i zaimplementowana walidacja, patrzyłeś w ten kod? (hint: spróbuj w moim przykładzie podstawić do zmiennej 'c' wartość nie numeryczną).

Plusem korzystania z metod magicznych jest czytelność w używaniu kodu. Nie interesują Cię żadne metody, korzystasz z naturalnego przypisywania i pobierania wartości zmiennych. Nie znam przypadku w którym magiczne __set() i __get() nie zastąpiłyby z powodzeniem starych set() i get(). Za to właśnie pojawia się wspomniana już przeze mnie naturalność używania kodu.

Nie musisz tego lubić, nie musisz używać, ale proszę użyj jakiegoś argumentu który ma rzeczywiste podstawy, a nie takiego który można obalić w ciągu kiliku minut po jakimś zastanowieniu się.

Ten post edytował mysz 17.03.2007, 10:07:08
Go to the top of the page
+Quote Post
Turgon
post
Post #11





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


I apropos walidacji. Można to jeszcze prościej. Klasa dziedziczy po Validatorze (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) . W ten sposób otrzymuje jego metody do walidacji i po robocie (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
Banalny przykład:
  1. <?php
  2. interface iValidate{
  3. public function valid($var);
  4. }
  5.  
  6. class Validator implements iValidate{
  7. public function valid($var){
  8. if(ctype_alpha($var)){
  9. return true;
  10. }
  11. return false;
  12. }
  13. }
  14.  
  15. class Example extends Validator{
  16. protected $var = '';
  17.  
  18. public function __set($name,$value){
  19. if(!$this->valid($name)){
  20. throw new Exception('Nazwa "'.$name.'" nie przechodzi walidacji, więc zmienna nie może być edytowana!');
  21. }
  22. if(!isset($this->{$name})){
  23. throw new Exception('Wartość "'.$name.'" nie istnieje, więc nie może być edytowalna!');
  24. }
  25. $this->{$name} = $value;
  26. }
  27.  
  28. public function __get($name){
  29. if(!$this->valid($name)){
  30. throw new Exception('Nazwa "'.$name.'" nie przechodzi walidacji, więc zmienna nie może być pobierana!');
  31. }
  32. if(!isset($this->{$name})){
  33. throw new Exception('Wartość "'.$name.'" nie istnieje, więc nie może być pobierana!');
  34. }
  35. return $this->{$name};
  36. }
  37. }
  38. try{
  39.  
  40. $o = new example();
  41.  
  42. $o->var = 'Jakieś tam bzdury!';
  43.  
  44. echo $o->var;
  45.  
  46. $o->inna1 = 'Dupa'; 
  47. }
  48. catch(Exception $e){
  49. echo $e->getMessage();
  50. }
  51. ?>
Go to the top of the page
+Quote Post
mike
post
Post #12





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

Ostrzeżenie: (0%)
-----


Cytat(Turgon @ 17.03.2007, 10:34:08 ) *
I apropos walidacji. Można to jeszcze prościej. Klasa dziedziczy po Validatorze (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) . W ten sposób otrzymuje jego metody do walidacji i po robocie (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
No bez jaj. Toż to głupota.
A jeśli moja klasa to Samochód dziedzicząca po Pojazd ?
Dorzucanie takich mechanizmów za pomocą dziedziczenia to efekt niezrozumienia idei obiektowości i dziedziczenia.

Ten post edytował mike_mech 17.03.2007, 10:59:22
Go to the top of the page
+Quote Post
Turgon
post
Post #13





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


mike_mech: Nie obchodzą mnie idee. To ma działać szybko i jak należy. Jak chcesz być tak bardzo obiektowy. Dodaj mechanizm dodawania walidatorów
Go to the top of the page
+Quote Post
mysz
post
Post #14





Grupa: Zarejestrowani
Postów: 81
Pomógł: 0
Dołączył: 26.08.2006
Skąd: Szczecin

Ostrzeżenie: (0%)
-----


@Turgon: tutaj się przyłączam do mike_mech: średnie rozwiązanie. chcesz w ten sposób robić osobne klasy do sprawdzania każdej właściwości? Czy też różne interfejsy? Bez sensu. To akurat lepiej jest zrealizować w poszczególnych metodach.
Go to the top of the page
+Quote Post
athabus
post
Post #15





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Ja osobiście uważam, że metody __get i __set są raczej kiepskim wyborem. Jak dla mnie są bardzo nieczytelne - zawsze uważałem, że klasa jednoznacznie musi definiować swoje API - jeśli mam dość skomplikowaną klasę z kilkoma polami różnego typu to wkrada się tam zbyt duża komplikacja - zbyt dużo if'ów itp. W zasadzie tylko kilka razy udało mi się znaleźć rozsądne zastosowanie do metod magicznych - w większości przypadków preferuje zwykłe setZmienna() i getZmienna() gdyż od razu widze, które pola były przewidziane do publicznego dostępu. Choć w początkowej fazie narzuca to więcej bezsensownego klepania to potem jest znacznie wygodniejsze w użytkowaniu i łatwiejsze w dokumentacji.
Go to the top of the page
+Quote Post
Turgon
post
Post #16





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


Mysz: Rozwiązanie najprostsze =] Pisane z palca (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) Bez konkretnego zastosowania. Ja inaczej to rozwiązuje u mnie w klasach (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Z resztą __set i __get są niesamowicie przydatne przy interfejsie obiektowym np. dla danych usera (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Ten post edytował Turgon 17.03.2007, 12:00:28
Go to the top of the page
+Quote Post
mysz
post
Post #17





Grupa: Zarejestrowani
Postów: 81
Pomógł: 0
Dołączył: 26.08.2006
Skąd: Szczecin

Ostrzeżenie: (0%)
-----


@athabus: właśnie w tym rzecz: Ty stawiasz na czyelność kodu, ja stawiam na elegancję i naturalność używania. No i kwestia tego, że dla mnie taki szkielet jak zaprezentowałem na początku jest czytelny i nie narzekam, ale to już indywidualna kwestia :)

@Turgon: Ja nie neguję używania metod magicznych, wręcz czasem je nadużywam, ale są dla mnie niezmiernie wygodne. Chodziło mi tylko o metodę walidacji przedtsawiona przez Ciebie powyżej :)
Go to the top of the page
+Quote Post
Strzałek
post
Post #18





Grupa: Przyjaciele php.pl
Postów: 384
Pomógł: 6
Dołączył: 11.09.2004
Skąd: Grodzisk Mazowiecki

Ostrzeżenie: (0%)
-----


Cytat
mike_mech: Nie obchodzą mnie idee. To ma działać szybko i jak należy. Jak chcesz być tak bardzo obiektowy. Dodaj mechanizm dodawania walidatorów


WOW. Dobra to powiedz mi ile tych cennych 0,0001 sek. tracisz i ile takich wielkich projektów napisałeś żebyś musiał aż tak oszczędzać na czasie, co bardziej jest niewygodną niż oszczędnością ?
Go to the top of the page
+Quote Post
menic
post
Post #19





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

Ostrzeżenie: (0%)
-----


Ja preferuje metody getXXX setXXX. Bardzo zwieksza czytelnośc kodu. Ale nie jestem też przeciwnikiem metod magicznych. Co jedne bedzie dobre w konkretnym przypadku, to drugie niekoniecznie. Trzymanie sie na siłe jednego, jest ble (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
Go to the top of the page
+Quote Post
Turgon
post
Post #20





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

Ostrzeżenie: (0%)
-----


Strzałek: No-comment (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Dla mnie to jest prostsze. Jak chce pisać coś czytelniejszego niż kodzik na kilka godzin, to piszę w innym stylu.

Ten post edytował Turgon 17.03.2007, 12:18:04
Go to the top of the page
+Quote Post

3 Stron V   1 2 3 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.08.2025 - 10:32