![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 141 Pomógł: 1 Dołączył: 2.12.2008 Ostrzeżenie: (0%) ![]() ![]() |
Witam, ostatnio zasnatawia mnie czy w PHP można w jakiś sposób opakowąć klasę w swego rodzaju taki szablon (nie mam na myśli interfejsu). Może jest na to jakiś wzrorzec.
Załużmy że mam klasę (pisane z palca):
i teraz chciałbym aby klasa Read korzystała z jakiegoś szablonu w którym wymuszone by miała ustawione parametry $msg_* W ten sposób poprostu kolejne modele pisał bym w stylu
A odwołując się do modelu móglbym ustawiac parametry dla np komunikatów:
|
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 395 Pomógł: 80 Dołączył: 24.08.2009 Ostrzeżenie: (0%) ![]() ![]() |
Jeżeli dobrze rozumiem to chcesz aby obiekty miały dostęp do właściwości $msg_*, jeśli tak to wystarczy przenieść te właściwości do klasy abstrakcyjnej, uczynić je dziedziczonymi i dodać odpowiednie gettery i settery.
-------------------- |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 141 Pomógł: 1 Dołączył: 2.12.2008 Ostrzeżenie: (0%) ![]() ![]() |
tak ale jak utworzę klasę abstrakcyjną dziedziczoną,
to Model_Read już dziedziczy po czymś, nie można dziedziczyć po dwóch rzeczach, musiało by to wyglądać tak np Model_Read extends Klasa_Abstrakcyjna Klasa Abstrakcyjna extends Model_Data_Abstract Pytanie tylko czy w Model_Read dam radę odwoływać się bezkonfliktowo do metod Model_Data_Abstract ? Jeżeli zawiera on np właściwosći publiczne to czy z poziomu Model_Read uzyskam do nich dostęp (musiałbym chyba w Klasa_Abstract definiować, opakowywanie metod lub iplementowac interfejs, który mi to umożliwią). |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
Raczej:
Model_Read extends Model_Data_Abstract Model_Data_Abstract extends Klasa_Abstrakcyjna implements YYY_Interface Klasa_Abstrakcyjna implements XYZ_Interface, ZXY_Interface Ten post edytował CuteOne 26.09.2012, 09:55:42 |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 6 380 Pomógł: 1116 Dołączył: 30.08.2006 Ostrzeżenie: (0%) ![]() ![]() |
Mogą cię też zainteresować http://php.net/manual/en/language.oop5.traits.php
-------------------- |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 141 Pomógł: 1 Dołączył: 2.12.2008 Ostrzeżenie: (0%) ![]() ![]() |
Raczej: Model_Read extends Model_Data_Abstract Model_Data_Abstract extends Klasa_Abstrakcyjna implements YYY_Interface Klasa_Abstrakcyjna implements XYZ_Interface, ZXY_Interface Tak to by mi rozwiązało problem, tylko Mode_Data_Abstract dziedziczy po czymś tam znowu (nie wspominając że należy do bibliotek finalnych których nie mogę ruszyć). Wiec zostaje w punkcie wyjścia ![]() Mogą cię też zainteresować http://php.net/manual/en/language.oop5.traits.php To rozwiązanie od 5.4 (niestety nie zastosuje tego). |
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Napisz jakie będzie przeznaczenie tego kodu, dlaczego tak chciałbyś to zrealizować, bo wygląda na to, że próbujesz rozwiązać jakiś problem w niewłaściwy sposób.
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 141 Pomógł: 1 Dołączył: 2.12.2008 Ostrzeżenie: (0%) ![]() ![]() |
Ogólnie wygląda to tak że buduję sobie listę modeli opartych na Zend_Db_Table i każdy model muszę opakowywać (wewnątrz) w listę właściwości typu:
public $msg_... Zawierają one domyślny komunikat, są publiczne aby można było samodzielnie np przekazać treść komunikatów, np standardowy komunikat dla akcji usuwania byłby np "pomyślnie usunięto pozycję", ale np dla konkretnego zdarzenia lepiej wygląda komunikat, który go bezpośrednio dotyczy, np dla listy produktu, informacje o tym że produkt został usunięty. Niestety Zend_Db_Table sobie nie rozszerzę o takie właściwości. Problem opakowywania nie jest jakimś dyskomfortem bo z IDE łatwo się to rozwiązuje, ale zastanawia mnie czy nie można tego rozwiązać inaczej aby zgodnie z DRY elementy które się powtarzają ulokować w jednym miejscu i w jakiś sposób implementować je tam gdzie są potrzebne. Inny problem który napotykam podczas realizacji modeli jest taki że integrując go z zewnętrzna bazą która nie była projektowana pod kątem wymogów jakie narzuca Zend_Db_Table, muszę pisać obok metody do obsługi Danych (by uniemożliwić przkazanie innych wartości niż warunki jakie dostarcza baza). Niestety to rozwiązuję tworząc nowy obiekt Np dla Model_Products, tworzę object Model_Data_Products, do którego przekazuję listę parametrów (a on mi je parsuje). Choć wolałbym to inaczej rozwiązać (właśnie poprzez jakieś dziedziczenie, by wewnątrz klasy tylko się odwoływać do metod z Model_Data_Products). Ale obecnie moja wiedza chyba w tych tematach jest ograniczona, bo nie mam innego pomysłu jak to rozwiązać, bo nie da się dwa razy podziedziczyć po innej klasie, nie tworząc przy tym dwóch klass. Skoro Model_Products dziedziczy po Zend_Db_Table_Abstract to nie podziedzice już po Model_Data_Products, owszem są interfejsy, ale przy nich nadal pojawia się problem z właściwościami. Z tym że Model_Data_Products dziedziczy po Model_Data_Abstract i jak bym chciał to rozwiązać tak aby mieć dostęp do metod innej klawy w obecnej klasie musiało by wyglądać to tak: 1) Model_Products extends Model_Data_Products 2) Model_Data_Products extends Model_Data_Abstract 3) Model_Data_Abstract extends Zend_Db_Table_Abstract Z tym że w pkt 1 chyba nie będę miał dostępu do metod z punktu 3 przez $this-> ? A jeszcze jak bym chciał tu wprowadzić szablon dla tych komunikatów to musiałbym wpleść kolejne zależności, albo wklepać je do Model_Data_Abstract Trochę chyba za bardzo przekombinowane by to było. |
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Przede wszystkim, zacznij korzystać z normalnych przestrzeni nazw. PHP 5.3.0 ma już ponad 3 lata!
Problem tkwi zupełnie gdzie indziej - tak jak podejrzewałem źle zabrałeś się do swojego prawdziwego problemu, tj. wyświetlania użytkownikowi komunikatów. Model jest częścią aplikacji, która w ogóle nie powinna interesować się takimi pierdołami. Model ma za zadanie jedynie zwrócić informację o poprawnym wykonaniu operacji, tj. jakaś metoda z publicznego interfejsu powinna zwrócić true. Natomiast w przypadku niepowodzenia rzucenie wyjątku jest niemal zawsze odpowiednim rozwiązaniem. Wyjątek to również miejsce na zamieszczenie dokładniej informacji o błędzie. Oczywiście, takie dane nie powinny być prezentowane użytkownikowi. Ustawienie odpowiedniego komunikatu będzie raczej leżało w gestii obiektu korzystającego z modelu, często będzie to kontroler, bądź inny model. Samo ustawienie czy też zwrócenie treści komunikatu powinno być oddelegowane do osobnego obiektu. Obiekt ten mógłby mieć prosty interfejs: Gdzie $key to klucz komunikatu, np. entity.remove.success, entity.create.failure czy notification.entity_created.success. Opcjonalny argument $object to obiekt, którego dotyczy komunikat - umożliwiłby on spersonalizowanie komunikatu, np. Wiadomość "Hej xajart" została wysłana pomyślnie!. |
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 141 Pomógł: 1 Dołączył: 2.12.2008 Ostrzeżenie: (0%) ![]() ![]() |
Okej, tylko nie rozumie do końca jak w Zendzie obsługiwać te błędy.
Jeżeli zrobię w metodzie:
To nie wie co powinienem zawrzeć w "catch", jeżeli wywali się zapytanie to fajnie by było mi to zapisać do logów (tutaj pewnie jakaś metodę opartą o Zend_Log musiał bym sobie napisać), ale muszę również użytkownika jakoś o tym poinformować w przyzwoity sposób, tylko jak w kontrolerze mam złapać ten wyjątek? Nie wstawię przecież: W necie nie mogą jakiegoś sensownego przykładu znaleźć. |
|
|
![]()
Post
#11
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
1. Raczej nie powinieneś przy każdym zapytani stosować bloku try-catch, o ile rzeczywiście nie chcesz sensownie obsłużyć błędu. Logi? Oczywiście, tak! Ale przecież nie będziesz kodu odpowiedzialnego za zapis tych logów powtarzał za każdym razem. Gdzieś w jakimś "wyższym" miejscu aplikacji, utwórz blok try-catch, który wyłapie Ci wszystkie wyjątki typu Zend_Db_Exception wygenerowane przez aplikację (zapewne Zend już takie coś ma), tam wykonaj zapis logów, a użytkownika przekieruj do statycznej strony z informacją o wewnętrznym błędzie serwera (kod odpowiedzi: 500 Internal Server Error). Żadnych dodatkowych informacji poza sugestią odświeżenia strony nie powinno tam być - bo i po co?
|
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 6 380 Pomógł: 1116 Dołączył: 30.08.2006 Ostrzeżenie: (0%) ![]() ![]() |
Zawsze możesz rozszerzyć Zend_Db_Exception o jakąś własną klasę i w niej dorobić ogólne logowanie. Ewentualnie jakiś singleton kolejkujący wszystkie wyjątki Logger::addLog($e->getMessage);
-------------------- |
|
|
![]() ![]() |
![]() |
Aktualny czas: 20.08.2025 - 14:57 |