Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: W jakim celu stosuje się wzorce projektowe?
Forum PHP.pl > Forum > PHP > Object-oriented programming
Jarod
Czytam sobie o wzorcach projektowych. Przerabiam właśnie wzorzc obserwatora (rozumiem, że jest ich dużo więcej niż w książce "php Zaawans. progr." ?). Już miałem sie pytać o wyjaśnienie bo strasznie zamotany ale jakoś załapałem. Po co się stosuje takie wzorce? Często wydaje mi się, że człowiek opracowując swój algorytm na rozwiązanie problemu może stosować nieświadomie jakiś wzorzc albo tworzyć swój własny. Czy wzorzec to nie inaczej algorytm? Czy wzorce to coś takiego jak MVC albo inaczej czy MVC jest wzorcem?

Wracając do wzorca obserwator. Autor pisze coś takiego:
Cytat
Bardzo często mamy do czynienia z danymi, które ulegają zmianie wraz z upływem czasu.Powiedzmy, że dysponujemy pewnymi elementami GUI, które powinny wyświetlać te dane, a także odświeżać zawartość , gdy dane ulegają zmianie. Jak to osiągnąć? Można przekazywać nowe dane do odpowiedniej metody komponentu, GUI, tak aby mógł on odświeżyć swoją zawatość. Co jednak gdy nie jest oczywiste jak często te dane będą aktualizowane a interfejs użytkownika powinien być odswieżany przy każdej zmianie?


Autor sugeruje, że rozwiązaniem jest wzorzec obserwatora. Przestudiowałem go bardzo dokładnie, próbując zrozumieć dziwny tok rozumowania autorów tej książki. I myslę, że to jedna wielka bujda, przynajmniej w php.

Wiadomo, że php wykonywany jest po stronie serwera. Załóżmy, że ktoś wporwadzi jakieś zmiany w bazie, to, aby sprawdzić (czyli obserwator) czy dane uległy zmianie musi np wydać odpowiednie zapytanie sql. Ale jak często ma to sprawdzać? Czyli trzebaby ustawić na szcztwno, że strona ma się odświeżać co 30sekund.


Albo ja nie łapie tego albo to jest otalnie pojeba**
dr_bonzo
MVC tez jest wzorcem.

Wzorzec to sprawdzone rozwiazanie na czesto pojawiajacy sie problem/zagadnienie (ktory musisz dopasowac do swojej konkretnej sytuacji)
Tylko jest to bardziej zbior obiektow ich relacje miedzy soba, odpowiedzialnosc itd, niz dokladny przebieg sortowania Quick Sort.

Np. Chcesz miec aplikacje okienkowa -- np. arkusz kalkulacyjny (jak Excel) i chcesz zeby po zmienieniu danych w tabeli aktualizowaly sie wszystkie wykresy utworzone na podstawie tych danych -- stosujesz Obserwatora.


Cytat
Wiadomo, że php wykonywany jest po stronie serwera. Załóżmy, że ktoś wporwadzi jakieś zmiany w bazie, to, aby sprawdzić (czyli obserwator) czy dane uległy zmianie musi np wydać odpowiednie zapytanie sql. Ale jak często ma to sprawdzać? Czyli trzebaby ustawić na szcztwno, że strona ma się odświeżać co 30sekund.


Musialbyc miec jakas funkcje w bazie ktora po zmianie/aktualizacji danych wysylala by powiadomienie do usera zeby odswiezyl strone -- wtedy to bylby wzorzec Obserwator (tylko tego chyba (99%) nie da sie zrealizowac)

Cytat
Często wydaje mi się, że człowiek opracowując swój algorytm na rozwiązanie problemu może stosować nieświadomie jakiś wzorzc albo tworzyć swój własny

Jak najbardziej.
Jarod
Ok. Jeszcze jedno. Poniżej jest przykład z książki:
  1. <?php
  2.  
  3. interface Observer {
  4.  public function update(Observable $subject); 
  5. }
  6.  
  7.  
  8. abstract class Widget implements Observer {
  9.  
  10. protected $internalData = array();
  11.  
  12. abstract public function draw();
  13.  
  14. public function update(Observable $subject) {
  15. $this->internalData = $subject->getData();
  16. }
  17. }
  18.  
  19.  
  20. class BasicWidget extends Widget {
  21.  
  22. function construct() {}
  23.  
  24. public function draw() {
  25.  
  26. $html = '<table border=1 width=130>';
  27. $html .= '<tr><td colspan=3 bgcolor=#cccccc><b>Informacje o instrumencie<b></td></tr>';
  28.  
  29. $numRekords = count($this->internalData);
  30.  
  31. for ($i=0; $i<$numRekords; $i++) {
  32. $inst = $this->internalData[0];
  33. $prices = $this->internalData[1];
  34. $years = $this->internalData[2];
  35. $html .= '<tr><td>'.$inst[$i].'</td><td>'.$prices[$i].'</td><td>'.$years[$i].'</td></tr>';
  36. }
  37.  
  38. $html .= '</table><bgr>';
  39. echo $html;
  40. }
  41. }
  42.  
  43.  
  44. abstract class Observable {
  45. private $observers = array();
  46.  
  47. public function addObserver(Observer $observer) {
  48. array_push($this->observers, $observer);
  49. }
  50.  
  51. public function notifyObservers() {
  52. for ($i=0; $i < count($this->observers); $i++) {
  53. $widget = $this->observers[$i];
  54. $widget->update($this);
  55. }
  56. }
  57. }
  58.  
  59. class DataSource extends Observable {
  60. private $names;
  61. private $prices;
  62. private $years;
  63.  
  64. function __construct() {
  65. $this->names = array();
  66. $this->prices = array();
  67. $this->years = array();
  68. }
  69.  
  70. public function addRecord($name, $price, $year) {
  71. array_push($this->names, $name);
  72. array_push($this->prices, $price);
  73. array_push($this->years, $year);
  74. $this->notifyObservers();
  75. }
  76.  
  77. public function getData() {
  78. return array($this->names, $this->prices, $this->years);
  79. }
  80. }
  81.  
  82. $dat = new DataSource();
  83. $widgetA = new BasicWidget();
  84.  
  85. $dat->addObserver($widgetA);
  86.  
  87. $dat->addRecord('beben','12zl',1992);
  88. $dat->addRecord('gitara','13zl',1993);
  89. $dat->addRecord('pianino','14zl',1994);
  90. $dat->addRecord('pianino','14zl',1994);
  91.  
  92.  
  93. $widgetA->draw();
  94. ?>



W metodzie
  1. <?php
  2. public function notifyObservers() {
  3. for ($i=0; $i < count($this->observers); $i++) {
  4. $widget = $this->observers[$i];
  5. $widget->update($this);
  6. }
  7. }
  8. ?>


a dokładniej w update przekazywane jest samo $this. Co dokładnie jest w tej metodzie przekazywane? Obeikt $widget ?
Cysiaczek
Tak. Pseudozmienna $this wskazuje na aktualny egzemplarz klasy.
athabus
J4r0d - co do Twojego pierwszego pytania, to wzorce po prostu slużą do uniwersalnego rozwiązywania powtarzalnych problemów w miarę efektywny sposób. Prawde mówiąc w php wzorce stosuje się znacznie rzadzeiej niż w innych językach programowania - tak przynajmniej wynika z moich obserwacji - duża część skryptów jest w miarę prosta i służy do generowania stron www, a wzorce znajdują zastosowanie raczej tam, gdzie kod jest skomplikowany/duży. Co oczywiście nie znaczy, że się z nich nie korzysta - czasami nawet w małych projektach warto zastosować wzorce a i php służy często do bardziej zaawansownych rzeczy niż tworzenie prostej stronki.

Tak z życia:
Np. Tutaj rozwiązaniem okazał się wzorzec obserwatora (może trochę niesformalizowany)klik
Tutaj z kolei masz przykład singletona klik - dodaj sobie jakiś tekst echo 'cos' w konstruktorze i destruktorze i zobacz co się stanie jeśli nie będzie to singleton.
Jarod
Cytat(dr_bonzo @ 26.08.2006, 22:58 ) *
Musialbyc miec jakas funkcje w bazie ktora po zmianie/aktualizacji danych wysylala by powiadomienie do usera zeby odswiezyl strone -- wtedy to bylby wzorzec Obserwator (tylko tego chyba (99%) nie da sie zrealizowac)


To po co go stosować skoro nie spełnia w php (bo rozumiem, że w innym języku nie byłoby takie proeblemu) swojego zadania?

Cytat(athabus @ 27.08.2006, 10:04 ) *
Tak z życia:
Np. Tutaj rozwiązaniem okazał się wzorzec obserwatora (może trochę niesformalizowany)klik


Nie rozumiem tego kodu tongue.gif
athabus
Cytat
Nie rozumiem tego kodu tongue.gif


Spójrz na to co napisał mike_mech - masz tam klasę książka i drugą kolekcję książek. Teraz Książka ma pewne cechy, które nie są inicjowane na początku, a tylko gdy są potrzebne -> tu to była liczba rozdzaiłów.
Teraz np. wzorzec obserwatora możesz wykorzystać aby uzyskać działanie, że gdy jedna książka z kolekcji pobiera swoje rozdziały to wszystkie pozostałe mają zrobić to samo. Zauważ jednak, że między klasą book a bookCollection nie ma żadnego powiazania "na sztywno". Po prostu klasa książka może "wysłać komunikat" do dowolneog obserwującego ją obiektu w stylu "pobrałam swoje rozdziały" -> a obserwator zdecyduje -> skoro ona pobrała swoje rozdziały to niech zrobią to inne książki. Inny obserwator książki mógłby zdecydować "skoro ona pobrała swoje rozdziały" to ja mogę je wyświetlić itp itd. Bez wzorca obserwatora musiałbyś mocno powiązać ze sobą oba typy klas co nie zawsze jest wskazane.

Cytat
To po co go stosować skoro nie spełnia w php (bo rozumiem, że w innym języku nie byłoby takie proeblemu) swojego zadania?


Dr_bonzo miał raczej na myśli, że akurat w tym przypadku w php trudno ten wzorzec wykorzystać, ale można go wykorzystać w inny sposób.
Taifun
a ja mam pytanie czy pisząc aplikacje PHP często stosujecie wzorce czy robicie tak jak wam wygodniej czyli struktura?
athabus
A dlaczego uważasz, że używanie wzorca nie jest wygodne?

Wzorce ogólnie opłaca się implementować gdy aplikacja jest większa - wiadomo, że przy małych stronkach to nie ma sensu, gdy natomiast kodu jest dużo i istnieje możliwość, że w przyszłości będzie trzeba go przerabiać to opłaca się stosować wszystko, co pozwoli na zaprowadzenie jakiegoś porządku czyli wzorce projektowe, frameworki, warstwy abstrakcji itp itd.
nospor
Cytat
tak jak wam wygodniej czyli struktura
I dlaczego uważasz, że wygodniej to "struktura"? I dlaczego uważasz, że jak ktoś nie używa wzorców to nie pisze obiektowo? Obiektówka nie ma nic do wzorców - można pisać obiektowo i nie używać wzorców.
Taifun
Piszę ponieważ ciężko przejść na obiektówkę z pisania strukturalnego...
Macie jakieś wskazówki dla początkujących chcących uporządkować kod PHP?
athabus
Spróbuj wdrożyć jakiś framework obiektowy - zobaczysz jak działa obiektowość i jakie są zalety.
Nie da się z dnia na dzień przejść na obiektowe programowanie bo to jest zupełnie inna filozofia - trzeba po prostu pisać i uczyć się.
kalipek
ja mam wskazówkę - przeczytaj porządną książkę w temacie, jeśli nie chcesz tracić miesięcy na robienie syfu, by w końcu zorientować się o co naprawdę chodzi w OOP

http://www.amazon.com/gp/product/067233016...43FMCKRMSBRZBM2
Taifun
Nie lepiej zostać przy strukturalnym programowaniu.
Jako programista PHP muszę znać obiektowe programowanie żeby mnie gdzieś do pracy przyjęli? smile.gif
@kalipek
A masz coś po polsku?
athabus
Zdefiniuj "gdzieś".

Jeśli chcesz klepać stronki po 500zł i sprzedawać je na allegro (lub pracować jako pracownik w firmie, która tak robi) to nie musisz wiele umieć.

Prawdziwe pieniądze zarabiają jednak specjaliści, którzy robią ciekawe rzeczy a nie klepią ciągle proste stronki czy cms'y. Jeśli chcesz np. pisać oprogramowanie backendowe, różnego rodzaju oprogramowanie specjalistyczne to tak, musisz znać programowanie obiektowe. Zresztą programowanie obiektowe to dopiero początek - musisz umieć znacznie więcej.
thek
I vice versa nospor wink.gif Nawet pisząc strukturalnie można zaprowadzić kodzie ideologię wzorców, czego dobrym przykładem byłoby podzielenie kodu strukturalnego na "warstwy". Jarod, Taifun: na początku przetwarzasz żądanie ( kontroler/prezenter ), potem wywołujesz z bazy na jego podstawie dane Ci potrzebne ( model ) i umieszczasz je w strukturze generowanej strony (widok). Różnica między podejściem obiektowym i strukturalnym wynikała by tu jedynie z "innego opakowania". Ale sam schemat/zamysł pozostałby niezmieniony. Przykładowo ja tak w części starych serwisów robię. Nie mogę zmienić użytego narzędzia, przypuśćmy ograniczenie do określonej wersji MySQL, PHP i systemu szablonów. Pozostaje mi więc jedynie takie usystematyzowanie kodu strukturalnego, by zmieniając jedynie plik odpowiedzialny za pojedyncze zadanie, zrobić to nie burząc/nie modyfikując działania innych opartych o te same komponenty (jakieś shared typu footer czy head) czy w oparciu o ów modyfikowany, poprawić jakość i czytelność kodu, nieraz typowego spaghetti. Nie jest to jawne i wprost trzymanie się wzorca, ale pewnych jego założeń, które w późniejszym etapie (konserwacja i aktualizacja kodu) w wymierny sposób wpływają na czas obcowania z kodem będącym już poprawionym.
kalipek
Mam coś po polsku i czytałem coś po polsku, tylko żadna z tych pozycji nie robiła z OOP czegoś tak oczywistego i prostego, jak jest w rzeczywistości. Więc nic nie polecę, ucz się angielskiego tongue.gif
LSM
@Jarod : Dokładnie miałem te same myśli co Ty kiedy przerobiłem ten wzorzec w tej książce.
Uważam, że ta kniga jest o tyle dobra że przynajmniej zmusza do myślenia hehe. Ja ten wzorzec uznałem za bezsensowny w przypadku PHP który jest językiem skryptowym bez pojęcia "wątków". Oczywiście jakaś tam implementacja wątków w PHP jest, można ją symulować CRON'em etc. ale to tylko prowizorka "prawdziwych wątków".

Przykład z książki jest nietrafiony i naciągany - być może. Przynajmniej trudno zrozumieć intencje autorów. Nie są one sprecyzowane.

Jednak wzorzec obserwator możnaby użyć do systemu, który komunikuje się z innymi systemami zewnętrznymi za pomocą różnych protokołów (FTP, SOAP, RPC, HTTP etc).
Wtedy (jednak ponownie symulując wątki w CRON) uruchamiamy wywoływacz który spr. zmianę źródeł danych i steruje widokiem. Również jest możliwe otrzymanie inf. jako pierwszej z zew. systemu gdy ten zechce się zaktualizować swoje dane.

Przykłąd z życia: system kredytowy (frontend dla banków) do zarządzania sprzedażą kredytów. Bierze pod uwagę różne sposoby komunikacji banków i ich źródła danych które z jednej strony są odświeżane przez "wątek symulowany" PHP'a z drugiej są otrzymywane inf. generowane z systemów bankowych przez protokół SOAP, lub HTTP (czyli system bankowy łączy się wywołując nasz PHPowski URL z ustalonymi wartościami GET tak na chłopski rozum) :-)
irmidjusz
Chciałbym tu dodać, że wzorzec Obserwator jak najbardziej może mieć użyteczne zastosowanie w PHP, gdy aplikacja napisana jest obiektowo. Ma to miejsce, gdy w czasie przetwarzania requesta obiekt musi informować o zmianie swojego stanu inne obiekty dołączane dynamicznie (na podstawie np. parametrów requesta, stanu sesji, ustawień aplikacji, wyników obliczeń, rezultatu zapytań do bazy itp.), bądź przekazywać im jakieś wygenerowane dane (częściowe bądź pełne) itd. Może to dziać się raz jak i wiele razy (wszystko w ramach jednokrotnego obsłużenia żądania HTTP).
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.