Witam, mam kilka męczących mnie kwestii dotyczących wzorców projektowych oraz programowania OOP.
Chcę napisać jakąś sensowną aplikację w PHP - wiem ilu "anty-zwolenników" jest od PHP (więc może omińmy temat "sensowna aplikacja w PHP") - do mnie to nie do końca trafia. Przejdźmy do kwestii.
Załóżmy, że chcę zbudować sobie moduł do obsługi plików - np. niech będzie to .XML, .INI czy choćby .YML
Kwestia 1: (struktura katalogów)
Nazwa Modulu
- Klasy
-- Klasa XML
-- KLASA INI
-- KLASA YML- Klasy Abstrakcyjne
-- Klasa Abstrakcyjna- Interfejsy
-- Interfejs 1
-- Interfejs 2
Czy taka struktura będzie odpowiednia ? - Na moje oko będzie to w miarę czytelne.
Kwestia 2: (klasy abstrakcyjne)
Wiadomo, że chodzi o plik, ale nie wiadomo jaki będzie to plik, więc mógłbym stworzyć sobie klasę abstrakcyjna np o nazwie ,,File".
W klasie stworzę metodę getExtension(), która pobiera rozszerzenie pliku.
Teraz klasa XML jest w stanie dziedziczyć po klasie abstrakcyjnej metodę getExtension() i sprawdzić czy podany plik posiada na pewno rozszerzenie XML - uwolniłoby mnie to od tworzenia tej metody dla każdej klasy.
Ale jakie będzie rozwiązanie, gdy zajdzie potrzeba odziedziczyć coś po innej klasy ? Odetnę sobie skrzydła ponieważ odziedziczyć mogę tylko po jednej klasie.
Czy takie rozwiązania mają sens ? Czy może przy mniejszych projektach nie warto tworzyć klas abstrakcyjnych ?
Kwestia 3: (interfejsy)
Biorąc pod uwagę nadal powyższy przykład, mógłbym zrobić interfejs, w którym zdefiniuje getExtension() i implementować go dla poszczególnych klas - tylko po co jeśli w powyższym przykładzie będzie lepiej zastosować klasę abstrakcyjną, która dostarczy już daną metodę.
Jakie jest dobre zastosowanie interfejsów w PHP ? - W chwili obecnej mam wrażenie, że jest to dobre rozwiązanie jeśli oddajemy jakiś projekt, a jedna (lub więcej) z klas podczas użycia będzie w potrzebie utworzenia kilku metod. (świetnym przykładem okazała, by się tutaj Java i klasa, która implementuje np. MouseListener).
Kwestia 4: (wyjątki)
Wiadomo, że w zależności od tego co wystąpi, chciałbym zwracać jakiś błąd, komunikat, etc.
Nie lubię zwracać stringów - np.
return "wszystko ok";
- bezsensu.
Jestem zwyczajny zwracać kody błędów, komunikatów.
Do tej pory robiłem to sobie (zazwyczaj) w jakiejś klasie, gdzie nazwie zmiennej (statycznej) odpowiadała kodowi np. 04.
Do tego robiłem stosowny słownik w innej klasie np. TA_SAMA_NAZWA_ZMIENNEJ_TXT = komunikat wypluty dla użytkownika.
W jednym pliku mogę stworzyć klasę, a w niej wszystkie wyjątki dla danego modułu (czyli klas XML, YML, INI) wiadomo, że będzie to mniej przejrzyste. W moim punkcie widzenia nie byłoby sensu, a żeby tworzyć każdą klasę wyjątków, a w niej takowe kody błędów etc.
Może właśnie tutaj z pomocą przychodzą interfejsy ? W folderze "Interfejsy" można dodać folder "Exception" i umieścić w nim interfejsy np. z końcówką "Exception", a każda klasa by implementowała dany interfejs.
Jak to mądrze rozwiązać - wydaje mi się, że na bazie interfejsów byłoby to w miarę czytelnie zrobione - są jednak i wady:
- ilość plików
- dodatkowy folder
- klasa już na start musi implementować jakiś interfejs.
PS. A może nie próbować odkrywać koła na nowo i po prostu w klasie zrobić zmienne const ?
Kwestia 5: (wzorzec projektowy)
Jaki wzorzec projektowy byłoby warto zastosować np. do aplikacji sieciowej ?
Mianowicie:
Uruchamiamy skrypt ---> skrypt wczytuje dane konfiguracyjne o serwerze, porcie
Skrypt podłącza się do serwera ---> słucha jakie polecenie dostaję (np. stwórz plik o nazwie "start.xml") (oczywiście też dostałby takie polecenie danym kodem np. "55").
Skrypt odwołuje się do modułu tworzenia plików .XML ---> dzięki metodzie, która znajduję się w klasie tworzy plik.
W razie potrzeby skrypt wypluwa coś do konsoli ---> JEŚLI zachodzi taka potrzeba.
Kwestia 6: (trait)
Od PHP 5.4 dostaliśmy "funkcję" korzystania z trait. Wygląda to bardzo podobnie do "wielokrotnego dziedziczenia".
Jednak nie spotkałem, się jeszcze, by ktoś korzystał jakoś specjalnie z tego "geniuszu".
Jak sądzicie - czy warto z tego korzystać - i w jakich sytuacjach skoro tak ?
Z góry dziękuje za wszystkie odpowiedzi!