Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: lista obiektow
Forum PHP.pl > Forum > PHP > Object-oriented programming
Gecco
problem prawodopodobnie jest prosty ale nigdzie nie moglem znalesc tego - pewnie zle szukam blinksmiley.gif

dopiero zaczynam z programowaniem obiektowy i dla mnie to troche abstrakcja

zalozmy ze mamy wyswietlic liste 10 ostatnich newsow. mam klase 'news' aby pobrac dane trzeba podac w konstruktorze id, ten z koleji ustawia wszystkie dane po koleji. problem jest taki zeby pobrac kazdego newsa a) musimy znac jego id cool.gif za kazdym razem wykonuje zapytanie mysql, wiec w sumie wykonujemy 11 zapytan wiec rozwiazanie jest do wiadomo czego sciana.gif

pytanie jak to napisac aby to bylo dobrze
webdice
Tworzysz sobie metodę getLastNews która nie przyjmuje żadnego argumentu, a następnie drugą która pobiera news o danym id.

  1. <?php
  2. class news
  3. {
  4. public function getLastNews ()
  5. {
  6. $query = mysql_query ('SELECT ... LIMIT 10');
  7. }
  8.  
  9. public function getNewsById ($id)
  10. {
  11. $query = mysql_query ('SELECT ... WHERE `id` = ' . $id);
  12. }
  13. }
  14. ?>
jarek_bolo
No tylko, że w tym momencie burzy nam to zasady, że obiekt = news, JEDEN news. No i klasa News staje się miejscem skupiającym funkcje newsów. Co jest (jak gdzieś kiedyś czytałem) typowe dla nie pełnego myślenia obiektowego, sam też tak mam smile.gif

Ja skłaniał bym się do wykorzystania również Data Access Objects.
Mamy automatycznie dwa razy więcej obiektów, bo każdy z obiektów w systemie, który istnieje w bazie powinien mieć swój DAO.
Więcej znajdziesz tutaj: http://www.odi.ch/prog/design/php/guide.php

Wtedy dajesz:
  1. <?php
  2. $newsDAO = new NewsDAO($db);
  3. $lastNewses = $newsDAO->getLastNewses();
  4. ?>

Co zwróci powyższa metoda wybierz sam:
1) tablica wypełniona już obiektami News,
2) asocjacyjna tablica zbudowana z wyniku zapytania,
3) obiekt $statment na którym było wykonane execute()
Za dwoma ostatnimi przemawia względna niezależność od siebie klas News i NewsDAO, chociaż w tym wypadku te klasy są skazane na współpracę ze sobą, więc wygoda pierwszego rozwiązania też jest ok.
Sedziwoj
@jarek_bolo
Jak ma pobrać ostatnie News, to ma to zrobić, czyli zwraca kolekcje (tablicę, iterator, czy cokolwiek) obiektów News.
Sam obiekt DAO wykonuje jedną kwerendę, pobierającą 10 krotek, a na podstawie wyniku tworzy obiekty News i wpakowuje w kolekcję którą zwraca.
Skoro mamy warstwę abstrakcji dostępu do danych, to niech ona robi co ma robić, a nie my musimy jeszcze potem się z tym bawić, po to jest rozdzielenie odpowiedzialności, aby w danej części robić to co mamy, nic więcej (czyli w akcji nie bawimy się SQL, czy operacjami związanymi z bazą danych).
jarek_bolo
@Sedziwoj
Przecież jedna z możliwości jakie metoda DAO może zwracać w moim rozwiązaniu jest dokładnie tym o czym piszesz, a to że podałem jeszcze inne możliwości (zwracanie surowych danych, bądź obiektu zapytania) wynika z faktu, że od tego czytania o obiektówce czasem za bardzo człowiek stara się wypełniać zalecenia podawane w artykułach. No bo czy nie piszą tak, że poszczególne klasy (obiekty) powinny być od siebie niezależne, aby zwiększyć szansę ich ponownego użycia w innym projekcie. Skoro tak, to klasa NewsDAO nie powinna mieć w sobie żadnych odwołań do innej klasy (obiektu). Ale z drugiej strony, oczywistym jest, że NewsDAO jest od dostępu do Newsów, więc wykroczeniem przeciw obiektowości nie będzie jeśli obie klasy (DAO i VO) będą siebie wymagały.
Więc jak najbardziej się z Tobą zgadzam.
Sedziwoj
Zależności powinno się niwelować, ale tu mamy po prostu wydzielenie funkcjonalności do innej klasy, DAO, i logiczne jest że są z sobą ściśle związane, jak produkt i fabryka.
To tylko rozbicie funkcjonalności, tak aby było łatwiej zmieniać i dodawać nową, jak i zrozumieć działanie.

Głównym powodem mojego poprzedniego postu było, bezsensowność stosowania innego zwracania, jak już coś robimy to róbmy to dobrze. Bo jak by wykorzystać inną metodę niż kolekcję obiektów News, to przy każdym wywołaniu musieliśmy coś więcej robić, a nie o to chodzi w tym wszystkim, bo robimy aby było łatwiej niż trudniej.

Zresztą, to co mówię można zaobserwować w Propel, gdzie są News które są AR, oraz NewsPeer które są DAO. (chyba że mi się nazewnictwo miesza, ale chyba nie).
Gdzie DAO korzysta z obiektu klasy Criteria przy wybieraniu danych.
jarek_bolo
No i gitara, zgadzam się w pełni z Twoją argumentacją, wszak sam taką myśl dopuszczałem tylko z uwagi na mniejsze doświadczenie niepotrzebnie dopuszczałem też inne możliwości.

Czyli czasami obiektowe myślenie to nie koniecznie musi sprowadzać się do postrzegania wszystkiego w postaci atomowych obiektów, tego w publikacjach nie piszą.
Czasem, na ogólnym poziomie abstrakcji, dany obiekt po wejściu w szczegóły może składać się z kilku obiektów. I tak tutaj mamy ogólnie w systemie coś takiego jak Newsy, jest to swego rodzaju obiekt, którego implementujemy przy pomocy dwóch obiektów VO i DAO.
Gecco
@Sedziwoj

moglbys przelozyc swoja wypowiedz na jakies przykladowy kod? nie musi to byc nic skomplikowanego, z gory thx
Sedziwoj
@Gecco
Nie będę pisał czegoś co już jest napisane
http://propel.phpdb.org/trac/wiki/Users/Do...n/1.2/BasicCRUD
Tu masz przykład wykorzystania tego w ORM, tylko że on daje o wiele więcej.
Mała kopia z powyższego linku:
  1. <?php
  2. // 1) Fetch an object by primary key
  3.  
  4. $myBook = BookPeer::retrieveByPK(1);
  5.  
  6. // 2) update the values & save() it.
  7.  
  8. $myBook ->setTitle("War & Peace");
  9. $myBook->save();
  10. ?>

BookPeer to właśnie DAO, metoda retrieveByPK() pobiera jeden wiersz o zadanym kluczu głównym, oczywiście zwraca go jako obiekt AR czyli Book, metody set*() ustawiają wartości pól, get*() pobierają, save() zapisuje aktualny stan obiektu do bazy. W tym przypadku save() wywołuje update, ale jak stworzysz obiekt Book i nadasz mu wartości i dasz save() to wtedy wykona insert.
Co do pobierania wielu to masz metodę w BookPeer::doSelect( Criteria $c ), która zwraca array obiektów (choć lepiej było aby zwracało iterator, ale może w nowej wersji 1.3 to zmienili) Book, jak nie ma spełniających Criteria to zwraca pustą tablicę.
Co do Criteria, czyli warunków to znów kopię dam:
  1. <?php
  2. $c = new Criteria();
  3. $cton1 = $c->getNewCriterion(AuthorPeer::FIRST_NAME, "Leo");
  4. $cton2 = $c->getNewCriterion(AuthorPeer::LAST_NAME, array("Tolstoy", "Dostoevsky", "Bakhtin"), Criteria::IN);
  5.  
  6. // combine them
  7. $cton1->addOr($cton2);
  8.  
  9. // add to Criteria
  10. $c->add($cton1);
  11. ?>

co odpowiada
  1. SELECT ... FROM author WHERE (author.FIRST_NAME = 'Leo' OR author.LAST_NAME IN ('Tolstoy', 'Dostoevsky', 'Bakhtin'));

i taki obiekt $c przekazujesz do BookPeer::doSelect() i ono wybiera te rekordy co spełniają te kryteria.
viking
Albo poczytaj (i zastosuj) http://framework.zend.com/manual/en/zend.d...ble.rowset.html Nawet podane przykłady po drobnej podmianie nazw będą pasowały.
Sedziwoj
@viking
Tylko że Propel ma większe możliwości, bo on generuje klasy, więc mają specyficzną dla siebie budowę. Bardzo ważnym atutem generowania klas jest to, że w np. Eclipse+PDT masz podpowiadanie metod, a to bardzo przyspiesza pisanie kodu, nie trzeba pamiętać, czy zerkać jak i z czym jest powiązane, tyczy się to pól jaki i powiązań między tabelami, do tego Propel generuje nam SQL do tworzenia zdefiniowanych w XML tabel, lub odwrotnie generuje nam na podstawie istniejącej bazy danych.

Ale nie rozpoczynajmy dyskusji, co czyim zdaniem jest lepsze. Trzeba przestawić różnice, a autor sam dobierze to co mu będzie bardziej podobać.
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.