Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dziedziczenie, struktura klas i tabel
Forum PHP.pl > Forum > PHP > Object-oriented programming
Tarcil
Witam wszystkich.

W projekcie nad którym pracuję ma się znaleźć 5 działów: newsy, artykuły (posegregowane w kategoraich), pliki (również kategorie), projekty(bez kategorii) i linki(bez kategorii).
Napisałem juz skrypt obsługujący newsy, dodawanie, przeglądanie, tagi i komentarze. Chciałem przejść do kolejnego etapu - artykułów. I "naszła mnie" refleksja.

Czy zamiast pisać to strukturalnie, nie lepiej zbudować strukturę klas i z niej obsługiwać nie tylko artykuły, ale też projekty, pliki i linki? W końcu są to tylko rekordy w bazie, z których każdy ma swój ID, jakąś nazwę i opis (w przypadku artykułu to jest tekst artykuły, ale to i tak pole text w mysql). Mogłyby to być więc dane składowe klasy. Pozostałe informacje (np. w przypadku pliku bylyby to nr kategorii, wielkość pliku oraz link do pliku) można by przechowywać w danej składowej $data, która byłaby tablicą.

Te dane utworzyłyby zestaw danych klasy Item. Klasa item miałaby jeszcze metody: addNewItem, deleteItem, updateItem, które odpowiednio: dodają itema, usuwają lub zmieniają już istniejący item.

Do tego trzeba by utworzyć oczywiście 4 klasy dziedziczące po Item, a więc: articleItem, projectItem, fileItem i linkItem. Zadaniem tych klas byłoby obsługiwanie tych danych i metod, które nie są wspólne dla wszystkich rodzajów itemów. Właściwie to głównie chodziłoby o takie zaimplementowanie w nich funkcji __tostring, żeby wyświetlenie obiektu wstawiało od razu potrzebny kod na stronie (czyli nazwę pliku, datę publikacji, link, wilekość, typ pliku itd. itd.).

Jak to wygląda jeśli popatrzy się okiem kogoś bardziej doświadczonego ode mnie? (to byłaby moja trzecia od początku napisana samodzielnie klasa, więc na pewno wiele mi jeszcze trzeba). Jest tu gdzieś jakiś błąd w rozumowaniu?

I od razu, wiążące się z tym zagadnienie: tabele bazy danych. Tworzyć 4 tabele dla każdego rodzaju itema osobno, czy stworzyć jedną, zbierającą wszystkie właściwości wszystkich rodzajów itemów? 4 to zawsze kłopot, trzeba za każdym razem pamiętać, jakiego typu jest potrzebny item i wybierać odpowiednią tabelę w bazie. Z kolei 1 to wszystko w jednym miejscu, ale dużo dziur (bo nie wszystkie pola będą wykorzystywane przez dany typ itema). Jest też sprawa tego, że jeśli wykorzystuję dziedziczenie to chyba bardziej naturalne jest odtworzenie struktury dziedziczonych danych w strukturze tabeli (czyli 1 tabela items z tylko wspólnymi polami, a druga tabela itemsProperties z czterema polami (propertyId, propertyItem, propertyName, propertyValue), gdzie dodawałbym właściwości niewspólne (czyli w przykładzie itemu typu plik byłoby to np. (23, 9, link, http://www.costam.gdzies).

Jeśli ktoś się przez to przebrnął, to najpierw gratuluję (żona mi powtarza,że z pisaniem u mnie kiepsko), a potem proszę o opinie, za które już teraz serdecznie dziękuję.
Grzesiek
Według mnie sam pomysł, wykorzystania programowania obiektowego jest dobry, zresztą pisanie obiektowow to zwykle dobry pomysł.

Co do samego projektu to jeżeli w tabeli ma być dużo dziur to rozsądne jest wykorzystanie 4 tabel.

Jedna klasa powiedzmy Article powinna reprezentować jeden wiersz z tabeli artykuły, taki obiekt sam siebie w zasadzie nie powinien dodawać do tabeli (addNewItem), więc to czy rekord ma byc update'owany czy dodany mógłbyś "rozkminiać" na podstawie tego czy masz w obiekcie zapisany Primary Key z tabeli, analogicznie z pozostałymi tabelami, oczywiście to tylko takie moje dywagacje i nie ma jednego najlepszego sposobu.

Zauważyłeś, że można zrobić to obiektowo, to dobry początek, teraz wykonaj projekt tak jak to widzisz (wykorzystując moje wskazówki lub nie), jak skończysz i spojrzysz na swój projekt będziesz miał o wiele lepsze wyobrażenie o tym co jak powinno działać co z czym łączyć i najprawdopodobniej ... będziesz myślał o tym żeby przepisać cały kod tongue.gif
Tarcil
Dzięki smile.gif
Zabieram się powoli do "popychania" sprawy do przodu. Dam znać, jak skończę, co mi tam wyszło. A z tym pisaniem kodu od początku to znam to już dobrze, hehe i pewnie się tak skończy (bo np. klasę mySql, którą napisałem tydizeń temu już bym pozmieniał, lepsze pomysły mam na parę rzeczy). W każdym bądź razie dzięki za wskazówki, trochę mi pomogły poukładać sobie to w głowie.

Pozdrawiam
Przemek "Tarcil"

edit: 16.01.2009 12:32

Witam smile.gif

Klasa napisana. W czasie pisania zrezygnowałem jednak z dziedziczenia. Z dwóch powodów:
1. W klasie podrzędnej wyszedł mi konstruktor, który wywoływał konstruktor klasy nadrzędnej z jednym parametrem. Wyglądało to tak:
  1. <?php
  2. class articleItem
  3. {
  4. public function __construct(){
  5.  parent::__construct('article');
  6.  }
  7. }
  8. ?>

Uznałem, że to bezsensu, i wywołuję teraz obiekt Item przekazując do konstruktora klasy Item typ "itema", czyli np.:
  1. <?php
  2. $item = new Item('file');
  3. ?>


2. W pierwszym zamyśle chciałem dzięki odpowiednio przygotowanej metodzie __tostring() wyświetlać od razu całą stronę z informacjami. Ale to wymagałoby wprowadzenia do klasy kodu XHTML, a to nie wydaje mi się być dobrą praktyką (później są problemy z użyciem klasy w innym projekcie). Więc będę po prostu w odpowiednich miejscach strony wywoływał odpowiednie zmienne obiektu i je wyświetlał.

3. Jeśli chodzi o tabele MySQL to zdecydowałem się na rozwiązanie 4 tabelowe: Tabela item przechowuje dane, które są wspólne dla wszystkich typów itemów, pozostałe przechowują dane specyficzne dla danego typu. Połączone są oczywiście polem id.

Zdaję sobie sprawę, że nie jest to najlepsza możliwa klasa. Muszę jeszcze dorzucić jakąś obsługę błędów (albo pokuszę się o wyjątki?), pewnie kilka rzeczy jeszcze dałoby się poprawić, ale jestem zadowolony - działa i mogę zaryzykować stwierdzenie, że pisałem (i widziałem) gorsze.

Dzięki dla Grześka jeszcze raz i pozdrawiam smile.gif
Przemek "Tarcil"
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.