Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: OOP
Forum PHP.pl > Forum > PHP
Kuziu
Witam,

Tak się zastanawiam nad sensem stosowania Klas w php.
Np. mam klasy: Users, News, Forum itp.

I teraz na stronie głównej serwisu chcę wyswietlic aktywnych userow, newsy ostatnie i ostatnie topicki na forum.

Muszę tworzyć 3 obiekty ... a jak wstawię wiecej rzeczy na storne glowną to jeszcze wiecej.

Przy językach nawet takich jak ActionScript Flash'a ma to sens gdyz obiekt jest tworzony raz i dziala az do zamknięcia.
W php natomiast kazdorazowe utworzenie 3 - 6 obiektów z 20 nie uzytymi wcale metodami takimi jak (dodaj posta czy usuń news'a) na stronie głównej daje nam stratę czasu generowania kodu.

Więc czy w php w ogole to ma sens ?
hwao
strata czasu/latwosc rozbudowy, mozliwosci

porownaj sobie ten wspolczynik i wyjdzie Ci
Kuziu
No tak ale np.
W Klasie users mam metodę getNick

I teraz w klasie Forum wyswietlając posty nie będę przecież wywoływał dla każdego z postów
  1. <?php
  2. $users->getNick($row['userid']);
  3. ?>


Tylko wykonam to wszystko w 1 zapytaniu Join'ując tabelę userów do postów z forum.

Więc troche ta obiektowość się zaciera.

Może coś źle kombinuję :/

Czy dzielić klasy np. na te wykonujące coś i te tylko czytające by np. wchodząc na stronę główną tylko zczytywać dane i nie wciągać niepotrzebnych metod zapisu ?
Wtedy były by podklasy zapisujące i czytające questionmark.gif
dr_bonzo
3 obiekty to pikus.

Jak pisal hwao: porzadek, elastycznosc, latwosc rozbudowy, przejrzystosc kodu...

Zawsze mozesz napisac serwis w asemblerze (razem z serwerem www) bedzie najszybszy i zuzyje najmniej pamieci. Tylko po co?
sobstel
Cytat(dr_bonzo @ 2006-02-14 12:50:39)
Zawsze mozesz napisac serwis w asemblerze (razem z serwerem www) bedzie najszybszy i zuzyje najmniej pamieci. Tylko po co?

co nie znaczy, ze zawsze nalezy wybierac elastycznosc i latwosc rozbudowy kosztem wydajnosci, zwlaszcza w WWW. porownanie do assemlera jest mocno naciągane, ale nie chcial bym tu rozpoczynac kolejnej dyskusji na temat jak lepiej : obeiktowo czy proceduralnie.

zastanawiam sie tylko jak rozwiazac problem, ktory opisal Kaziu z userem i forum...
Kuziu
No bo prawda jest taka że co to za obiektowość gdy mając metodę do pobierania nicka nie mogę z niej skorzystać bo opchłonie to zbyt dużo czasu.

I co to za obiektowość gdy nazwa metoda nie realizuje 1 konkretnego zadania a jest wykonaniem wielu czynnosci wykonywanych tez w innych metodach.

A czyż nie dzielenie na metody części zadań jest założeniem OOP ?
By 1 konkretna metoda wykonywała powierzone jej zadania i inne metody musiały by z niej korzystać a nie przerabiać podobny problem na swój własny sposób.
andrzejb
stworz sobie jedna wielka klase System i wywoluejsz sobie ja tylko raz tongue.gif zawsze jechalem proceduralnie, teraz jezeli jednak widze ze jakis element kody powtarza sie czesto wzucam go do System naprawde to jest piekne..
DzikiLis
Cytat(Kuziu @ 2006-02-15 00:08:52)
No bo prawda jest taka że co to za obiektowość gdy mając metodę do pobierania nicka nie mogę z niej skorzystać bo opchłonie to zbyt dużo czasu.


Twoje obecne podejście zbliżone jest do wzorca Domain Model. Niestety, w php wiąże się ze sporym narzutem związanym z tworzeniem/niszczeniem obiektów przy każdym zapytaniu do serwera WWW.

Można z tym walczyć, np. serializując klasy, pytanie tylko po co. php jest prawie jak język OO, a z reklam Żywca wiemy, co w praktyce oznacza to "prawie". winksmiley.jpg Lepiej zainteresuj się innymi wzorcami, bardziej odpowiadającymi specyficznemu charakterowi tego języka. Rzuć okiem na Data Mapper i Lazy Load. Poczytaj też o Enterprise Java Beans. Może takie podejście ci się spodoba.

1) Przychodzi żądanie wyświetlenia postów w danym wątku.
2) Kontroller przetwarza żądanie i wyznacza obiekt PostMapper do zajęcia się tą sprawą.
3) Obiekt mapper generuje klasy Post i każdą z nich zapełnia danymi, w tym odpowiednim obiektem User (autor posta). W sumie 1-2 zapytania SQL.
4) Przekazujesz je do widoku, który je sobie odpyta i wyświetli stronę z postami.

Obiekty Post ograniczają się do przenoszenia danych między warstwami aplikacji. Możesz je trochę uinteligentnić dorzucając im LazyLoad. Jeśli okaże się, że obiekt nie został zapełniony danymi z bazy danych, może zwrócić się do klasy PostMapper z prośbą o uzupełnienie go danymi. Psuje to trochę czystość wzorca, ale skutecznie chroni przed przypadkowym wyczyszczeniem pól w bazie danych.

I na koniec:

1) "Przedwczesna optymalizacja jest źródłem wszelkiego zła."
2) An OO Layered Approach To Web Apps
3) php 5. Obiekty, wzorce, narzędzia
DeyV
A wracając do podanego tu przykładu - warto pamiętać, że są systemy, które działają właśnie w ten sposób.

Przykładem jest osCommerce, który to, na jedno wywołanie potrafi wywołać nawet ze 100 zapytań, a mimo wszystko chodzi "w miarę" wydajnie, i cieszy się niesłabnącą popularnością. Jest to jednak możliwe dzięki specjalnie po temu zoptymalizowanej strukturze bazy danych, i nastawieniu się na proste i bardzo szybkie zapytania.

Innym przykładem jest eZ, który problem ten potraktował na jeszcze niższym poziomie, i rozbił na osobne tabele nawet wartości konkretnych pól - czyli np. 1 news potrafi być zapisany w 5 tabelach. Tutaj jednak okazało się to możliwe dzięki bardzo rozbudowanemu systemowi cache, który dzięki takiemu stricte obiektowemu podejściu daje rzeczywiście ogromne możliwości (choć nie ukrywam - jest bardzo trudny do zarządzania) - jednak doświadczenie pokazuje, że wydajność nadal pozostawia wiele do życzenia.

Rozwiązanie podane przez DzikiLis, choć okraszone terminologią, ktoa niejednego na początku odstrasza od zaprzyjaźnienia się z OOP - jest w rzeczywistości jednym z najprostrzych i najwydajniejszych, a jakiaś jego wariacja jest moją ulubioną techniką.

Pozwala bowiem na połączenie elastyczności OOP z wydajnością zapytań złożonych, zwracających nam, za jednym zamachem, większość potrzebnych nam danych.
Kuziu
Cytat(andrzejb @ 2006-02-15 03:05:25)
stworz sobie jedna wielka klase System i wywoluejsz sobie ja tylko raz tongue.gif zawsze jechalem proceduralnie, teraz jezeli jednak widze ze jakis element kody powtarza sie czesto wzucam go do System naprawde to jest piekne..

Nie wydaje CI się że to o czym mowisz to żadne OOP ?

T normalne funkcje tyle że je wrzuciłęś do 1 klasy, zupełnie bez sensu. Równie dobrze możesz zrobić zwykłe funkcje i to je wywoływać.

W OOP ważny jest podział na określone zadania, Klasa odpowiada za jakieś funkcje a każda z jej metod zajmuje się jej składnikami.
Dodatkowo 1 czynność powinna byćwykonywana tylko przez 1 metodę w klasie.

A w php to wszystko jest jakby troche naciąganym OOP to normalne proceduralne programowanie z użyciem funkcji.
DeyV
Oczywiście, że jeśli ktoś chciałby kodować tak, jak mówi andrzejb, to byłoby dokładnie tak, jak mówisz. Na szczeście szalone pomysły winksmiley.jpg andrzejb nie są jedynymi możliwymi.

Po krótkim okreśie czasu okazuje się, że te kilkadziesiąt milisekund, jakie trwa wykonanie skryptu, to barrdzo dużo czasu, a podejscie obiektowe może w znaczący sposób ułatwić pracę. I wcale nie ma potrzeby martwienia się tym, że obiekty muszą się tworzyć i usuwać tyle razy.
Oczywiście - wpływa to nieco na filozofię tworzenia api, i w php nie użyjemy racze takiego fajnego drzewa obiektów, jak np. w JS, to jednak odpowiednie podejście, i automatyzacja pewnych działań okazują się niesamowicie przydatne.

Szczególnie, że OOP to nie tylko drzewo obiektów. To również klasy i dziedziczenie oraz rozszeżanie metod, co jest najlepszym i najszybszym sposobem na tworzenie rozbudowanego i bezpiecznego kodu - przy znacznie mniejszym nakładzie pracy, niż w strukturalce.
NuLL
Cytat
zastanawiam sie tylko jak rozwiazac problem, ktory opisal Kaziu z userem i forum...


Zakladam ze forum to zamknieta aplikacja wiec po pierwsze w takich przypadkach tworzymy klasy macierzyste na dla danego typu obiektow. Majac obiekt uzytkownika jako obiekt ktory jest otoczka dla wpisu na bazie robimy klase np.
  1. <?php
  2.  
  3. class usersHome
  4. {
  5. public method searchById($iId)
  6. {
  7. //..
  8. }
  9. public function searchByNick($strNick)
  10. {
  11. //..
  12. }
  13. }
  14.  
  15. ?>

I tyle smile.gif

Ew mozna by stworzyc klase pod nazwe usersCollection jednak jej specyfika dzialania juz z nazwy powinna byc inna tak wiec zostawmy to na inna dyskusje o OOP bo nie chce peszyc za bardzo winksmiley.jpg
DeyV
A Ci, co lubią nowości, a nie lubią takich "okrężnych" rozwiązań, powinni zainteresować się nowością w światku php - biblioteką SDO (narazie tylko w PECL)

http://www.zend.com/pecl/tutorials/sdo.php

W końcu ktoś zdecydował się zakodować to na "twardo". I nawet jeśli nie będziemy z tego narazie mogli korzystać - naprawę dobrze wiedzieć, że w końcu jest to możliwe...
mike
Cytat(Kuziu @ 2006-02-15 11:25:28)
Dodatkowo 1 czynność powinna byćwykonywana tylko przez 1 metodę w klasie.

Dlaczego tak sądzisz?
To nie jest żaden wymóg ani żaden trand.

Przeciez po to klasy mają metody prywatne (oczywiścnie nie tylko po to) żeby miały się czym wspierać.
Często jedna czynność może być na tyle skomplikowana że można ją rozbić na kilka mniejszych składowych, wtedy wykonanie nadrzędnej czynności może wyglądać na przykład tak:
  1. <?php
  2.  
  3. class Klasa
  4. {
  5. // ...
  6. public function someFunction( params )
  7. {
  8. // ... Jakieś operacje
  9. $arrResult = $this->supportFunction( someParams )
  10. // ... Jakieś operacje
  11. }
  12.  
  13. private function supportFunction( someParams )
  14. {
  15. // ... Jakieś operacje
  16. }
  17. // ...
  18. }
  19. ?>

Nie staraj się wszystkiego umieszczać tylko w jednej funkcji, bo czasem będzie to niewygodne winksmiley.jpg
anopak
Cytat
zastanawiam sie tylko jak rozwiazac problem, ktory opisal Kaziu z userem i forum...


A gdyby klasa users posiadała metodę, która np zwracała by tylko i wyłącznie tekst podzapytania dla klasy get posts?
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.