Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [mvc] Problem z obsługą błędów, + Ocena obecnego kodu
Vengeance
post
Post #1





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Oto mały przykład "wycięty" z mojego, powstającego jeszcze frameworka (jak widac pisanego mniej wiecej wg zasad MVC).
Przy starcie aplikacji wywołujemy metode Application::run() która wybiera akcje oraz widok. Uruchamia akcje, która z kolei może poprzez 'return' zwrócić:
+ Obiekt dziedziczący z klasy Action - wtedy kontroler uruchomi tę akcje (w ten sposób obsługiwane są łańcuszki akcji.
+ Inne, dowolne dane - wtedy kontroler traktuje je jako wynik działania akcji(łańcuszka) i przekazuje go do widoku(poprzez konstruktor). Na końcu kontroler wyświetla widok.

Po 1. Powiedzcie co tu może być źle przezemnie zrozumiane itd. Co można poprawić/zmienić. Jestem otwarty na propozycje ;]

Po 2. Mam problem z obsłużeniem błędów akcji. Takich jak np. w akcji 'showNews' brak newsa w bazie danych. Na razie obsługuje to jako łańcuszek jednak problem pojawia się, gdy akcja 'showError' korzysta z innego widoku niż akcja 'showNews'. Trzeba by było jakoś sensownie ten widok podmieniać. Jak ?
Albo jak rozwiązań to "fajnie". Mam wrażenie (pewnie uzasadnione), że to co istnieje teraz jest dość felernym rozwiązaniem.

ps. nie chce wykorzystywać czegoś ala 'fallback-action' gdyz to umożliwia generowanie tylko jednego komunikatu błędu gdy ogólnie akcja się "spsuje".

Prosze o pomoc (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Model:
  1. <?php
  2. class NewsContainer
  3. {
  4.    public function getNewsByID($iID)
  5.    {
  6.       if($iID <> 1) throw new NewsNotFoundException();
  7.       return new News('Jakis Tytul', 'Jakas Tresc');
  8.    }
  9. }
  10.  
  11. class News
  12. {
  13.    public $title, $content;
  14.    public function __construct($title, $content)
  15.    {
  16.       $this->title = $title;
  17.       $this->content = $content;
  18.    }
  19. }
  20. ?>


Akcja:
  1. <?php
  2.  
  3.    class showNews extends Action
  4.    {
  5.       public function display()
  6.       {
  7.          try {
  8.             $model = new NewsContainer();   
  9.             $news = $model->getNewsByID(1);
  10.             return $news;
  11.          } catch(NewsNotFoundException $e) {
  12.             return new showError('Informacja', 'News o podanym ID nie istnieje');
  13.          }
  14.       }   
  15.    }
  16.  
  17. ?>


Widok:
  1. <?php
  2.  
  3.    class showNewsAsHTML extends View
  4.    {
  5.       private $news, $_template;
  6.  
  7.       public function __construct($oNewsRecord)
  8.       {
  9.          $this->news = $oNewsRecord;
  10.          $this->_template = new Smarty();
  11.       }
  12.  
  13.       public function display()
  14.       {
  15.          $this->_template->assign('news', $news);
  16.          $this->_template->display('html/showNews.tpl');
  17.       }   
  18.    }
  19.  
  20. ?>


Kontroler:
  1. <?php
  2.  
  3. class Application
  4. {
  5.       public function run()
  6.       {
  7.          $sActionName = $_GET['action'];
  8.          $sViewName = $_GET['view'];
  9.             
  10.          $mDataForView = $this->performAction(new $sActionName());
  11.          $oView = new $sViewName($mDataForView);
  12.          $oView->display();
  13.       }
  14.  
  15.       public function performAction(Action $oAction)
  16.       {
  17.          $result = $oAction->perform();
  18.          /* Obsługa łańcuszków akcji */
  19.          if($result instanceof Action)
  20.             $this->performAction($result);
  21.          else 
  22.             return $result;
  23.       }
  24. }
  25.  
  26. ?>


Ten post edytował Vengeance 1.03.2005, 16:48:44
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
chmolu
post
Post #2





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

Ostrzeżenie: (0%)
-----


Na początek, jako że jestem nowy na tym forum, chciałbym przywitać wszystkich forumowiczów (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Widzę, że i tu ludzie zmagają się z MVC.

Cytat
Przy starcie aplikacji wywołujemy metode Application::run() która wybiera akcje oraz widok. Uruchamia akcje, która z kolei może poprzez 'return' zwrócić:
+ Obiekt dziedziczący z klasy Action - wtedy kontroler uruchomi tę akcje (w ten sposób obsługiwane są łańcuszki akcji.

Osobiście uważam, że łańcuszki akcji prawie nigdy ci się nie przydadzą. Lepiej operacje typu 'Usuń newsa' -> 'usuń artykuł' umieszczać w jednej akcji wywołując kilka klas modelu. W swoim frameworku mam metodę forward($action) kontrolera, którą może wywołać inna akcja. Tak realizuję łańcuszek. To akcja wywołuje następne akcje. Plus jest taki, że można na przykład wywołać inną akcję przed uruchomieniem właściwej. Można to zrobić tak jak u ciebie - to też jest dobre rozwiązanie. U mnie by się ono nie sprawdziło. Ale, tak jak powiedziałem, w praktyce 'łańcuszki akcji' spotyka się bardzo rzadko.

Cytat
+ Inne, dowolne dane - wtedy kontroler traktuje je jako wynik działania akcji(łańcuszka) i przekazuje go do widoku(poprzez konstruktor). Na końcu kontroler wyświetla widok.

To jest ciekawe rozwiązanie. Można w ten sposób na przykład przekazać listę błędów Validatora formularzy.

Cytat
Po 2. Mam problem z obsłużeniem błędów akcji. Takich jak np. w akcji 'showNews' brak newsa w bazie danych. Na razie obsługuje to jako łańcuszek jednak problem pojawia się, gdy akcja 'showError' korzysta z innego widoku niż akcja 'showNews'. Trzeba by było jakoś sensownie ten widok podmieniać. Jak ?
Albo jak rozwiązań to "fajnie". Mam wrażenie (pewnie uzasadnione), że to co istnieje teraz jest dość felernym rozwiązaniem.

W moim frameworku nie ma akcji typu showNews/showArticle/showXX. To jest zadanie widoków. Przez akcję rozumiem coś, co zmienia model (addArticle, addNews, deleteNews). A zatem, jeśli http://www.mysite.com/index.php?view=showNews to wtedy nie ma potrzeby uruchamiania akcji. Odpalam tylko odpowiedni widok. Jeśli natomiast http://www.mysite.com/index.php?action=deleteNews to odpalam akcję, która decyduje, który widok wyświetlić (np. $controller->setView($name)).

Widoki w moim frameworku chcę rozwiązać podobnie jak to jest w WACT. Też będą komponenty, tagi, z tym, że to wszystko będzie oparte na drzewie DOM (tyle, że bez używania DOM::save/load - to muszę niestety napisać sam :/).

Jak rozwiązać problem błędów? Nie ma akcji typu showNews, więc sprawdzenia, czy dany news istnieje możesz dokonać w widoku. Nie wiem jak to będzie w smarty, bo odczuwam niechęć do tego systemu. Zobacz, jak to jest rozwiązane w WACT - IMHO znakomity sposób (z wykorzystaniem komponentów). A jeśli błąd wystąpi w akcji typu deleteNews to możesz przerwać akcję i wywołać setView('Error', $dane /* komunikaty o błędach */);

Są różne sposoby. Właśnie przez takie drobne wydawałoby się problemy MVC staje się strasznie trudne do implementacji :/. Ja też na razie nie mogę wymyślić, jak radzić sobie np. z błędami Validatora, czy z autoryzacją. Odezwij się na gg to może razem coś wymyślimy (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
3 Użytkowników czyta ten temat (3 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 7.10.2025 - 23:55