Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: metody i ich przeznaczenie
Forum PHP.pl > Forum > PHP > Object-oriented programming
bliitz
Witam

Mam pytanie odnośnie zasady tworzenia metod w klasach, przykładowo mamy następujący scenariusz. Tworzymy klasę Artykuły a w niej metody ( lub metodę ? ) odpowiedzialną(e) za pobranie wszystkich artykułów oraz tylko jednego artykułu.
Teraz moje pytanie czy lepiej stworzyć dwie metody np:
  1. get_article( $id )
  2. {
  3.  
  4. }
  5.  
  6. all_article()
  7. {
  8.  
  9. }


Czy może stworzyć jedną metodę, która w zależności od wystąpenia określonego parametru pobierze wszystkie artykuły bądź tylko jeden, np:

  1. articles( $all = NULL )
  2. {
  3.  
  4. }


Który z przedstawionych scenariuszy jest zgodny z kanonem programowania OOP, czy może jest na to jeszcze inny sposób?
erix
Skoro masz klasę odpowiedzialną za artykuły, to dlaczego do nazw metod dodajesz sufiks niepotrzebnie opisujący obiekt? winksmiley.jpg Skoro to obiekt-metoda, to wiadomo do czego ta ostatnia się odnosi.

IMHO lepiej zrobić dwie metody; bardziej intuicyjne w późniejszej obsłudze.
dr4ko
Poprawnym podejściem jest utworzenie dwóch klas ArticlesCollection i Article, metody get_article i get_all powinny się znajdować w ArticlesCollection i zwracać obiekty Article.
bliitz
co do nazw dzięki za wskazówkę smile.gif
natomiast w przypadku metod, jeśli różnią się tylko przykładowo warunkiem WHERE id=xxx, to pisanie 2 metod nie jest produkowaniem zbędnych linijek kodu?
skowron-line
Cytat(bliitz @ 22.12.2009, 12:08:21 ) *
co do nazw dzięki za wskazówkę smile.gif
natomiast w przypadku metod, jeśli różnią się tylko przykładowo warunkiem WHERE id=xxx, to pisanie 2 metod nie jest produkowaniem zbędnych linijek kodu?


Możesz sobie utworzyć metodę chronioną do której będziesz tylko przekazywał warunek jako parametr.
erix
Cytat
i get_all powinny się znajdować w ArticlesCollection i zwracać obiekty Article.

No dla mnie, to jest raczej przesada... Nie chodzi o sens logiczny, tylko wydajnościowy. IMHO lepiej jest w takiej sytuacji połączyć klasę kolekcji z artykułem; są Iteratory, to trzeba z nich korzystać.

Może i sieję herezje, ale co za dużo, to niezdrowo.
zzeus
Cytat(erix @ 22.12.2009, 12:12:26 ) *
No dla mnie, to jest raczej przesada... Nie chodzi o sens logiczny, tylko wydajnościowy. IMHO lepiej jest w takiej sytuacji połączyć klasę kolekcji z artykułem; są Iteratory, to trzeba z nich korzystać.

Może i sieję herezje, ale co za dużo, to niezdrowo.


Z czego będzie wynikać poprawa wydajności przy zastosowaniu kolekcji, skoro klasa kolekcji też utworzy x obiektów klasy Article i będzie je przechowywać w swojej strukturze ?
erix
Ano w tym, że implementujesz w jednej klasie dwa interfejsy - ArrayAccess i Iterator. Masz jedną klasę zamiast n-dziesięciu.
bliitz
zakładam, że stosowanie klasy kolekcji w przypadku gdy klasa tylko dodaje, edytuje i wyświetla artykuły jest troche jak strzelanie z armaty do komara?
zzeus
Nie zrozumiałem poprzednio, zamiast klas ArticleCollection i Article jedna klasa Article z implementacją ArrayAccess i Iterator. Tylko wówczas obiekt tej jednej klasy może być używany w dwóch różnych kontekstach, jako obiekt i kolekcja obiektów, to może prowadzić do błędów i lekkiego bałaganu, czy w związku z tym nie lepiej jednak rozdzielić to na dwie klasy ?

Cytat(bliitz @ 22.12.2009, 12:30:06 ) *
zakładam, że stosowanie klasy kolekcji w przypadku gdy klasa tylko dodaje, edytuje i wyświetla artykuły jest troche jak strzelanie z armaty do komara?

To prawda.
dr4ko
A umiecie przewidzieć że nie będą się pojawiać nowe funkcjonalności? Kiedyś popełniliśmy ten błąd i poszliśmy na skróty. Skończyło się na klasach mających po kilka tysięcy linii kodu.
erix
Cytat
to może prowadzić do błędów i lekkiego bałaganu

Bałaganu? Rozwijam podobne rozwiązanie już kilka miesięcy i wcale nie spowodowało to bałaganu... Błędów też nie ma, a to z tej racji, że metody wyszukiwania są po prostu metodami, odnoszenie się do danych bieżącego rekordu - przez tablicę, którą udostępnia ArrayAccess. Przesuwanie między obiektami - Iterator. Wszystko w jednej klasie i sobie radzi. smile.gif
zzeus
Możesz jakąś przykładową klasę pokazać ?
erix
Jak przykładową? Nie chce mi się teraz wycinać kodu, pokażę, jak mniej więcej z niej korzystam;
  1. $art = model('article')->getAll();
  2.  
  3. // ...
  4.  
  5. foreach($art as $a){
  6. echo $art['title'];
  7. }
  8.  
  9. $art['title'] = 'asdasd';
  10. $art->save();


Przesuwanie - funkcje iteratora (z których korzysta przecież foreach), odczyt danych z rekordu - offsetGet, zapis offsetSet.

Jeśli chodzi o filtrowanie, czy jakieś zaawansowane operacje, nikt nie zabroni przecież użyć dodatkowych metod (np. getCostam, która działa na wewnętrznym wskaźniku rekordu i zwraca, co trzeba). Jedna klasa abstrakcyjna, która odpowiada za I/O z bazy + dziecko, które przechowuje strukturę bazy i dodatkowe metody.

A filtry można przecież zrobić przeciążając metody iteratora z klasy abstrakcyjnej. winksmiley.jpg
LBO
Po co doradzacie używanie kolekcji, gdy w 95% wystarczy zwykła tablica?

Rozumiem, gdyby w PHP były kolekcje generyczne, ale nie ma! Implementacja wyspecjalizowanych kolekcji to zwyczajnie więcej pisaniny. Jest to nieefektywna rada, raczej uprzykrzająca programiście życie.
Szczególnie gdy taką kolekcje można stworzyć w razie prawdziwej, podyktowanej nowymi wymaganiami, potrzeby i zrobić to praktycznie przezroczyście implementując ArrayAccess.
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.