Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Pytanie Dotyczące OOP
frytek92
post 29.08.2010, 13:45:20
Post #1





Grupa: Zarejestrowani
Postów: 163
Pomógł: 10
Dołączył: 9.11.2007
Skąd: Goleniów

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


Witam

  1.  
  2. $oop = new test_class;
  3.  
  4. $oop->funkcja()->funkcja();
  5.  


Moje pytanie do czego służy takie wywoływanie metody ?, kiedy się to stosuje może jakiś przykład klasy w której mamy takie zastosowanie bo nie mogę pojąc dlaczego metody są wywoływane w taki sposób czyli "$oop->funkcja()->funkcja()"

Pozdrawiam


--------------------
Go to the top of the page
+Quote Post
wookieb
post 29.08.2010, 13:52:38
Post #2





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Praktycznie w każdej klasie ma to zastosowanie. Ładnie to wygląda w kodzie i nie trzeba za każdym razem przepisywać referencji do obiektu.


--------------------
Go to the top of the page
+Quote Post
Spawnm
post 29.08.2010, 13:59:54
Post #3





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




Cytat(frytek92 @ 29.08.2010, 14:45:20 ) *
... może jakiś przykład klasy w której mamy takie zastosowanie...

Chyba wszystkie klasy db tak mają
$rows=$db->from('table')->findAll( $ofset, 5);
Tak jest szybciej i czytelniej smile.gif
Go to the top of the page
+Quote Post
Crozin
post 29.08.2010, 16:08:02
Post #4





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Cytat
Moje pytanie do czego służy takie wywoływanie metody ?
Takie czyli jakie? Przecież to najnormalniejsze w świecie wywołanie metody na obiekcie i następnie wywołanie kolejnej na zwróconym obiekcie.
Cytat
bo nie mogę pojąc dlaczego metody są wywoływane w taki sposób czyli "$oop->funkcja()->funkcja()"
Kod
a = 1 + 2 + 3;

VS

a = 1;
a += 2;
a += 3;
To jest ta sama sytuacja - wyrażenia można łączyć.


Jeżeli natomiast metody jednego obiektu mają być "łączone" wtedy mamy do czynienia z tak zwanym fluent interface
Go to the top of the page
+Quote Post
frytek92
post 29.08.2010, 18:13:19
Post #5





Grupa: Zarejestrowani
Postów: 163
Pomógł: 10
Dołączył: 9.11.2007
Skąd: Goleniów

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


Wielkie dzięki zrozumiałem o co chodzi, temat do zamknięcia.

Pozdrawiam


--------------------
Go to the top of the page
+Quote Post
smentek
post 8.09.2010, 19:40:25
Post #6





Grupa: Zarejestrowani
Postów: 130
Pomógł: 11
Dołączył: 7.04.2003

Ostrzeżenie: (10%)
X----


Chyba warto by jeszcze dodać, że kodowanie w tym stylu CZĘSTO, nie jest dobrym rozwiązaniem. Można nawet powiedzieć że najczęściej będzie no oznaką słabego stylu kodowania.

Na tego typu Kod:
  1. $parowoz->wagonPierwszy()->wagonDrugi()->wagonTrzeci();


Anglosasi mają ukuty termin "train carsh". Wrak pociągu.

Na chłopski rozum: z reguły warto sprawdzić czy metoda, która miała zwrócić obiekt faktycznie go zwróciła. Zwłaszcza jeżeli zwaracane obiekty zależą od aktualnego stanu bazy.

Ponadto tego typu kod łamie podstawową zasade OOP o enkapsulacji obiektów. Staramy się Powiedzieć obiektowi co ma robić a nie wyciągać z niego bebechy a potem wyciągać bebechy z jego bebechów...

Z drugiej strony jeżeli uznamy że nie działamy na obiektach a na strukurach danych to w pewnych specyficznych sytuacjach powyższe rozwiązanie jest to do przyjęcia. Np. Język DQL w ORM doctrine...

Ten post edytował smentek 8.09.2010, 19:43:58


--------------------
.:SMENTEK:.
Go to the top of the page
+Quote Post
wookieb
post 8.09.2010, 19:42:49
Post #7





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Czy ty wiesz do czego służy method chaining oraz wiesz co to wyjątki? Czy wyczytałeś na jakimś blogu i bez zastanowienia powtarzasz?


--------------------
Go to the top of the page
+Quote Post
smentek
post 8.09.2010, 19:51:58
Post #8





Grupa: Zarejestrowani
Postów: 130
Pomógł: 11
Dołączył: 7.04.2003

Ostrzeżenie: (10%)
X----


Cytat(wookieb @ 8.09.2010, 20:42:49 ) *
Czy ty wiesz do czego służy method chaining oraz wiesz co to wyjątki? Czy wyczytałeś na jakimś blogu i bez zastanowienia powtarzasz?


Czytałem na Twoim tongue.gif. A tak poważnie, to co wiem a czego nie wiem jest nieistotne, jeśli chcesz się wypowiedzić pod moim adresem (także krytycznie) to odnieś się do tematu na który dyskutujemy najlepiej bez personalnych ataków. I poświęć temu więcej niż 2 zdania.


--------------------
.:SMENTEK:.
Go to the top of the page
+Quote Post
wookieb
post 8.09.2010, 21:03:04
Post #9





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat
Ponadto tego typu kod łamie podstawową zasade OOP o enkapsulacji obiektów. Staramy się Powiedzieć obiektowi co ma robić a nie wyciągać z niego bebechy a potem wyciągać bebechy z jego bebechów...

Gdzie ty tu widzisz złamanie zasadę enkapsulacji? Ja osobiście nigdzie.
Żeby było więcej niż dwa zdania dopowiem, że świat dotyka problem braku pszczół spowodowany dziwnym zjawiskiem uciekania wspomnianych osobników z uli.


--------------------
Go to the top of the page
+Quote Post
mike
post 8.09.2010, 21:26:13
Post #10





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

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


~wookieb są dwa aspekty takiego kodowania. Jeśli stosujemy typowe fluent interface to jest OK.
Jednym słowem kolejne wywołania na (tym samym) obiekcie tej samej klasy są w porządku.

Natomiast jeśli każda wywołanie jest na obiekcie innej klasy: $obiektKlasyA()->$obiektKlasyB()->$obiektKlasyC(); to już źle. I raczej powinno się tego unikać.
Go to the top of the page
+Quote Post
wookieb
post 8.09.2010, 21:34:58
Post #11





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat(mike @ 8.09.2010, 22:26:13 ) *
Natomiast jeśli każda wywołanie jest na obiekcie innej klasy: $obiektKlasyA()->$obiektKlasyB()->$obiektKlasyC(); to już źle. I raczej powinno się tego unikać.

Czyli rozumiem, że takie wywołanie jest złe?
  1. $form = new Form();
  2. $form->addElement(new Form_Element_Select('nazwa_pola')) // addElement nadal zwraca $form
  3. ->getElement('nazwa_pola')
  4. ->setValue('test');

Oczywiście istota problemu zaczyna się od getElement. Jeżeli tak to dlaczego?


--------------------
Go to the top of the page
+Quote Post
-=Peter=-
post 8.09.2010, 21:35:14
Post #12





Grupa: Zarejestrowani
Postów: 304
Pomógł: 51
Dołączył: 4.02.2005
Skąd: Kraków

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


smentek wyczytał to nie z blogu, a najprawdopodobniej z książki Czysty kod winksmiley.jpg @smentek - zwróć uwagę, że tutaj został poruszony temat fluent interface, czyli że każde wywołanie metody powoduje zwrócenie obiektu, na którego rzecz ta metoda została wywołana. Nie odpytujemy się obiektu x po to aby dostać obiekt y, z którego pobierzemy obiekt z. Tutaj cały czas operujemy na tym samym obiekcie. To jest całkowicie inna sytuacja, żadna zasada (enkapsulacji, demeter, czy Bóg wie czego) nie jest tutaj łamana winksmiley.jpg Tym tokiem rozumowania np. wzorce builder, query object, specification, które często korzystają z fluent interface (np. obiekt Doctrine_Query) jest objawem złego stylu kodowania...


--------------------
Go to the top of the page
+Quote Post
Crozin
post 8.09.2010, 21:40:00
Post #13





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Cytat
Natomiast jeśli każda wywołanie jest na obiekcie innej klasy: $obiektKlasyA()->$obiektKlasyB()->$obiektKlasyC(); to już źle. I raczej powinno się tego unikać.
Tak dla jasności, chodzi o przykładowo coś takiego:
  1. File file = new PlainTextFile("plik");
  2. Line line = file.getLine(0);
  3. String[] words = line.getWords();
  4. String word = words[0];
  5.  
  6. # VS
  7.  
  8. String word = new PlainTextFile("plik").getLine(0).getWords()[0];
Przykład trochę lipny, ale mamy tu do czynienia z trzema typami jakiś tam obiektów (plus tablica). W sumie przy jakiś dłuższych tasiemcach drugi zapis mógłby być nieco zbyt skomplikowany, jednak z reguły kończą się one na dwóch, trzech, maks. czterech metodach. Czy poza ewentualną czytelnością zapisu jakieś inne ale są? Bo nieco mnie zaintrygowałeś.

EDIT:
Ojej... na przyszłość muszę odświeżać temat przed dodaniem odpowiedzi, a nie po 10 minutach odpisywać tongue.gif

Ten post edytował Crozin 8.09.2010, 21:41:23
Go to the top of the page
+Quote Post
smentek
post 8.09.2010, 22:05:22
Post #14





Grupa: Zarejestrowani
Postów: 130
Pomógł: 11
Dołączył: 7.04.2003

Ostrzeżenie: (10%)
X----


To prawda -=Peter=- w "Czysty Kod" był o tym rozdział. winksmiley.jpg. Ale przecież sam na końcu swego postu podałem buildera z doctrine za przykład kiedy tego typu zapis bywa do zaakceptowania. Dlatego piszę "często" a nie "zawsze".
I prawdą jest to co piszę, że tego typu zapis niewłaściwie stosowany często kończy się kraksą.
Dzięki za odzew.


--------------------
.:SMENTEK:.
Go to the top of the page
+Quote Post
-=Peter=-
post 8.09.2010, 22:07:59
Post #15





Grupa: Zarejestrowani
Postów: 304
Pomógł: 51
Dołączył: 4.02.2005
Skąd: Kraków

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


@Crozin - tutaj raczej chodzi o:
  1. String word = new PlainTextFile("plik").getLine(0).getWords()[0];
  2.  
  3. //vs
  4.  
  5. String word = new PlainTextFile("plik").getFirstWordFromLine(0);
  6. //lub bardziej ogólnie
  7. String word = new PlainTextFile("plik").getWordFromLine(0, 0);


Chodzi o to, że w pierwszym przypadku odkrywamy implementację klasy PlainTextFile, to że obiekt tej klasy składa się z obiektów Line.

Inny bardziej jaskrawy przykład:
  1. class newsActions
  2. {
  3. public function doSave(...)
  4. {
  5. //... coś tam robię i na końcu przekierowanie
  6. $this->getController()->redirect(...);//"wraki pociągów" ;)
  7. //vs
  8. $this->redirect(...);
  9. }
  10. }


ukrywamy to, że korzystamy z front controllera aby zrobić przekierowanie. Np. w testach jednostkowych łatwiej nam w razie potrzeby przesłonić jedną metodę aby zrobić jakąś zaślepkę, niż przesłaniać dwie metody. Poza tym taki kod jest bardziej odporny na zmiany, bo co jeśli metoda redirect z kontrolera (zwróconego przez getController) zostanie przeniesiona gdzieś indziej? Czekają nas zmiany w wielu miejscach, zamiast w jednym, gdyż klasy są mocno zależne od siebie.


--------------------
Go to the top of the page
+Quote Post
Crozin
post 8.09.2010, 23:27:10
Post #16





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Hmm... tworzenie takich metod proxy jest jak najbardziej OK w przypadku takich właśnie pierdół jak "redirect". Jednak w nieco bardziej skomplikowanych przypadkach (ot chociażby już ten daremny przykład z plikiem/liniami/słowami) to już raczej średni pomysł:
1. Obiekt "nadrzędny" (tu PlainTextFile) nagle musiałby zawierać dziesiątki metod proxy
2. Obiekt ten utraciłby swoje znaczenie - nagle (z punktu widzenia interfejsu) stałby się jakimś potworkiem od wielu rzeczy
3. Koniec końców i tak pewnie wystąpiłaby metoda getLines()

Nie zgodziłbym się też tak do końca z tym odkrywaniem implementacji. To nie jest wyciąganie bebechów, tylko raczej wyciągnięcie udostępnianych danych (w tym przykładzie obiekty typu File pełniły niejako role kolekcji z dodatkowymi informacjami dot. tej kolekcji).

Zgodzę się za to z tym, że takie ukrywanie "pół-bebechów" przynosi pewne korzyści - jednak ma to swoją cenę.
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 13.08.2025 - 23:03