Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MVC] Widok nie odwołujący się bezpośrednio do modelu?
MacDada
post
Post #1





Grupa: Zarejestrowani
Postów: 47
Pomógł: 1
Dołączył: 24.06.2010
Skąd: Sopot

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


Hej,

przeczytałem kupę tematów o MVC na forum i zastanawia mnie tu jedna rzecz. Większość osób pokazuje schemat działania aplikacji jako taki:
1.) Kontroler rozpoznaje co użytkownik chce zrobić (np wyświetlić listę użytkowników).
2.) Kontroler odpala wtedy odpowiedni widok.
3.) Widok odpala model.
4.) Model przerabia co tam potrzebuje i zwraca dane do widoku.
5.) Widok prezentuje dane.

Co mnie dziwi to fakt, że w ten sposób jeśli zmienię model, to muszę ingerować też w pliki widoku. Jest on uzależniony od konkretnego modelu. No i widok bezpośrednio współpracuje z modelem, a kontroler pełni funkcję jedynie routera.

Czy w takim razie nie lepszy byłby schemat taki?
1.) Kontroler rozpoznaje co użytkownik chce zrobić (np wyświetlić listę użytkowników).
2.) Kontroler wybiera model i go odpala.
3.) Model przerabia co tam potrzebuje i zwraca dane do kontrolera.
4.) Kontroler wybiera widok i przekazuje mu dane od modelu.
5.) Widok wyświetla dane.

W ten sposób Kontroler rzeczywiście pełni funkcję pośredniczącą między warstwą danych i działań, a warstwą prezentacyjną. Mogę stworzyć różne widoki do reprezentowania tego samego typu danych, a jednocześnie mogę mieć wiele źródeł danych, które będą wyświetlane przez ten sam widok.

Co więcej upraszcza to schemat akcji, który może wyglądać tak:
1.) Kontroler rozpoznaje, co użytkownik chce zrobić (np dodać nowego użytkownika do bazy).
2.) Kontroler wybiera model i go odpala.
3.) Model przerabia co tam potrzebuje i zwraca dane do kontrolera (np kod błędu, kod sukcesu, itd.)
4.) Kontroler wybiera widok i przekazuje mu dane od modelu.
5.) Widok wyświetla dane.

Voila! Okazuje się w ten sposób, że model jest równoważny akcji. Model służy wszystkim operacjom na danych, kontroler służy rozpoznawaniu tego co chce użytkownik i tego co chce model, a widok służy do prezentowania danych przekazanych mu przez kontroler. Co więcej, jeśli widok zwróci błąd, to kontroler znów rozpoznaje co się dzieje i odpala odpowiedni model jako reakcję, np logger. Pure MVC?

Czy może jednak w takim podejściu tkwi jakiś błąd?
pozdr.

Ten post edytował MacDada 27.07.2010, 18:50:34
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Zyx
post
Post #2





Grupa: Zarejestrowani
Postów: 952
Pomógł: 154
Dołączył: 20.01.2007
Skąd: /dev/oracle

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


Jakie setki ifów? Słyszał waść o wyjątkach? (IMG:style_emoticons/default/smile.gif) Rzecz jest prosta: widok nie łapie wyjątków modelu, dzięki czemu może odebrać je kontroler i zareagować, kierując do standardowego systemu obsługi błędów modelu.

Jeśli chodzi o kwestię różnych typów widoków, umiejscowienie komunikacji niewiele zmienia. Podam Ci przykład w pseudokodzie:

  1. public function someAction()
  2. {
  3. switch($request->view)
  4. {
  5. case 'html':
  6. $view = new View_Something_Html;
  7. break;
  8. case 'xml':
  9. $view = new View_Something_Xml;
  10. break;
  11. case 'json':
  12. $view = new View_Something_Json;
  13. break;
  14. }
  15. $view->addModel('datasource', new Some_Model);
  16. return $view;
  17. } // end someAction();


Pamiętaj, że widok to nie tylko kod HTML (szablony), ale też logika prezentacji. Stronicowanie wyników ma sens w przypadku HTML-a, ale może nie mieć w formacie JSON lub PDF. Obsługa stronicowania to zadanie widoku - dzięki powyższemu podejściu, gdzie widok sam sobie pobiera dane, kontroler nie musi nawet wiedzieć, co dokładnie jest mu potrzebne do wykonania swojego zadania. Jeśli widok nie komunikuje się z modelem, kod ten musi wylądować w kontrolerze i wtedy nagle tu się pojawia mnóstwo ifów, a kod kontrolera staje się długi i przeładowany.

Ponadto warto zwrócić uwagę, że da się stworzyć tzw. uniwersalne widoki wielokrotnego przeznaczenia. Jest to coś, co ciężko uświadczyć we frameworkach, które warstwę widoku zredukowały do systemu szablonów. Mam sobie uniwersalny widok do wyświetlania listy elementów, który ma już wbudowaną obsługę stronicowania, sortowania, filtrowania i co tam sobie jeszcze wymarzysz. Jeśli wszystkie dane idą przez kontroler, a ja będę chciał gdzieś sobie zrobić listę elementów, muszę zrobić Ctrl+C i Ctrl+V całego kodu, a następnie go popoprawiać, lub też obudować sztuczną atrapą, która sprowadzi nas do MVC. Tymczasem ja sobie robię:

  1. public function displayMeSomethingAction()
  2. {
  3. $model = new Model_Something;
  4. $model->id = $request->getParam('id', null);
  5. $view = new View_List;
  6. $view->controllerIdentity = $this->getControllerIdentity(); // Dzięki temu widok może prawidłowo ustawić np. breadcrumbs i tytuł
  7. $view->addModel('list', $model);
  8.  
  9. return $view;
  10. } // end displayMeSomethingAction();


I co? 6 linijek, a ja mam listę elementów modelu z sortowaniem, stronicowaniem, filtrowaniem i wszystkim, co sobie tylko model zażyczy. Jeśli tę samą sztuczkę chcę powtórzyć w innym miejscu, mogę to od razu zrobić, bo jedyne, co tak naprawdę muszę zrobić, to wprowadzić model do gotowego widoku. Kod kontrolera jest krótki i przejrzysty, dzięki czemu po dodaniu uwierzytelniania i kontroli uprawnień wciąż nadaje się do czytania.

PS. Jeśli chcesz poeksperymentować z tego typu rzeczami, to obejrzyj sobie mój eksperymentalny framework stworzony do tego celu: http://github.com/zyxist/Trinity . Kod jest publicznie dostępny i możesz namacalnie sprawdzić, jak to działa w praktyce.

Ten post edytował Zyx 27.07.2010, 21:29:09
Go to the top of the page
+Quote Post

Posty w temacie


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

 



RSS Aktualny czas: 6.10.2025 - 04:10