Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: MVC raz jeszcze.
Forum PHP.pl > Forum > PHP
krzywy36
Wiem, że jest masa tematów na forum o tematyce MVC ale chyba w żadnym nie ma zawartych wszystkich zasad/odpowiedzi.
Zabrałem się ostatnio za OOP i chciałem napisać coś większego, przy okazji sprawdzając wiedzę, ale stwierdziłem, że trzeba oprzeć to na jakimś ogólnym wzorcu - jak tworzyć podstrony, struktury katalogów itp. i wtedy zacząłem interesować się MVC, tak więc:

Struktura katalogów:
Kod
|core/
|controllers/
|models/
|views/
|classes/
|web/
|index.php


Po kolei:
W core znajdują się klasy: router, db, controller, model, view itp.
w controllers znajdują się klasy kontrolerów, dziedziczące po klasie controller (abstrakcyjna klasa controller to ogólny zarys kontrolera)
models to samo, czyli dziedziczace po klasie model
views - widoki wybierane w zaleznosci od akcji
classes - inne klasy, narazie nic tam nie ma,
web - skrypty js, style itp.
index.php - dołącza odpowiednie pliki i "zaczyna akcje"

?url = nazwaKontrolera/ akcja/ param1/ param2/ paramN...

Router parsuje url i się zaczynają problemy:
1. sam powinienem tworzyć obiekt kontrolera czy jakaś metoda routera (czy moze jeszcze innej klasy?) powinna to robić?
2. gdzie trzymać obiekt controllera? po prostu w zmiennej, czy moze w obiekcie innej klasy* za to odpowiedzialnej, jeśli to drugie to jak powinna działać ta klasa?
3. zakładając, że mam już utworzony obiekt kontrolera, wywołuje jakaś jego metode (akcja) - teraz jest tworzony obiekt widoku? jeśli tak to gdzie go trzymać, w kontrolerze, czy w obiekcie innej klasy*?
4. chcąc być zgodnym z koncepcją MVC, to widok powinien poprzez model pobierac dane, więc obiekt modelu powinien być tworzony i trzymany w widoku czy może wcześniej w kontrolerze?
5. potem widok wyświetla dane blablabla... hmm, to co tak właściwie robi kontroler? bo idąc moim tokiem myślenia (który jest prawdopodobnie błędny) tylko, tworzy i przechowuje widok?

*inna klasa - rejestr?

Próbowałem coś pisać ale się pogubiłem, więc zwracam się do was o pomoc, móglby ktoś napisać klarowne odpowiedzi na moje pytania? Ewentualnie opisać co konkretnie powinien robić kontroler, model, widok i jakie są zależności pomiędzy nimi (co do czego powinno mieć dostęp, co może modyfikować co itp.)

Wszystkie sugestie/rady/krytyka na temat czegokolwiek co tu napisałem - mile widziane snitch.gif
Crozin
Ad. 1) Router sam w sobie powinien być odpowiedzialny wyłącznie za przetwarzanie "wejściowego identyfikatora" (np. URLa) na zestaw konkretnych parametrów potrzebnych aplikacji do wywołania odpowiedniego kontrolera. W skrócie: na podstawie URLa ma zwrócić nazwę kontrolera i zestaw parametrów dla niego.
Ad. 2) Tutaj wiele zależy od tego w jaki sposób zaimplementujesz sam wzorzec. Bardzo często za wywołanie kontrolera odpowiedzialny jest tak zwany Dispatcher (na podstawie danych z Routera wywołuje odpowiedni kontroler) - co do jego działania - chyba wszystko jest jasne
Ad. 3) To kontroler jest odpowiedzialny za zainicjalizowanie obiektu Widoku, czego nie musi zawsze robić (przykładowo: gdy akcja kończy się wykonaniem przekierowania na inną stronę)
Ad. 4) Kontroler jest odpowiedzialny za wrzucenie odpowiedniego Modelu do danego Widoku. Widok sam w sobie powinien operować na Interfejsach, a nie konkretnych Modelach (tj. powinna istnieć możliwość wrzucenia dowolnego Modelu implementującego wymagany(e) przez Widok Interfejs(y))
Ad. 5) Bo Kontroler właściwie powinien robić względnie niewiele. On odpowiedzialny jest za zainicjalizowanie Modelu(i) oraz odpowiednego Widoku. Może jakoś skonfigurować Model (ma on do tego takie prawo jak i Widok). Na niego możesz zrzucić odpowiedzialność za takie "poboczne" rzeczy jak na przykład kontrola dostępu do danej części strony itp.

Cytat
Ewentualnie opisać co konkretnie powinien robić kontroler, model, widok i jakie są zależności pomiędzy nimi (co do czego powinno mieć dostęp, co może modyfikować co itp.)
Tutaj polecałbym Ci jakieś artykuły na temat MVC, ale nie ze świata PHP. Dlaczego? Bo jeszcze nie widziałem żadnej PHPowej implementacji tego wzorca, która by była chociaż ideologicznie zgodna z tym wzorcem. Dodatkowo poczytaj też o innych wzorcach, które wywiodły się z MVC, jak na przykład MVP (model-view-presenter), który bardzo często jest pokazywany (w mniejszym czy większym stopniu) jako MVC - nigdy nie zrozumiem czemu... oba skróty są fajne :] - czy hierarchicznej odmianie MVC - HMVC (również ciekawy wzorzec, który pasuje do środowiska webowego).

PS. Jest 4:13 - nie odpowiadam za to co napisałem smile.gif

EDIT:
Odradzam też stosowanie wzorca Rejestru (przynajmniej dla "globalnego" zastosowania). Jest on wyjątkowo niewygodny (przykładowo: uniemożliwia rozpoznawanie typów obiektów przez różnego rodzaju IDE), ale przede wszystkim jest on niebezpieczny - pod indeks "controller" mógłbyś wrzucić dosłownie wszystko - a raczej powinna to być instancja obiektu Controller. Lepszym rozwiązaniem byłby tutaj Kontekst.
outsider
Cytat
Tutaj polecałbym Ci jakieś artykuły na temat MVC, ale nie ze świata PHP. Dlaczego? Bo jeszcze nie widziałem żadnej PHPowej implementacji tego wzorca, która by była chociaż ideologicznie zgodna z tym wzorcem.


napewno nie tylko ja, ale tez inny ucieszyli by sie gdybys zademonstrowal przynajmniej zarys tej prawidlowej implementacji smile.gif
Crozin
Powiedzmy, że mamy podstronę na której wyświetlamy użytkowników serwisu w tabelce (kolumny: nazwa, email, wiek, płeć, data rejestracji) oraz dzielimy ją po 50 wpisów na stronę.

Kontroler:
  1. $model = new MembersModel();
  2. $model->setPerPageLimit(50);
  3.  
  4. $view = new TableView($model);
Model:
  1. class MembersModel implements Sortable, Paginable {
  2. // Sortable interface
  3. protected $sortBy = 'name';
  4. protected $sortDir = 'ASC';
  5.  
  6. // Paginable interface
  7. protected $perPageLimit = 10;
  8. protected $currentPage = 1;
  9.  
  10. // Implementacja interfejsow (settery/gettery dla powyższych)
  11.  
  12. public function retrieve() {
  13. // pseudokod
  14. $sql = 'SELECT ... FROM ... ORDER BY $sortBy $sortDir LIMIT {$perPage * $currentPage}, $perPage';
  15. return $sql->fetch();
  16. }
  17. }
Widok
  1. class ... {
  2. if ($model instance of Paginable) {
  3. $model->setCurrentPage($currentPage);
  4.  
  5. // przygotuj listę stron do wyświetlenia itp. itd
  6. // np.:
  7. $totalItems = $model->getTotalItems();
  8. $totalPages = $totalItems / $model->getPerPageLimit()
  9. }
  10.  
  11. if ($model instance of Sortable) {
  12. $model->setSortBy($sortBy);
  13. $model->setSortDir($sortDir);
  14. }
  15. }
  16.  
  17. // i potem w jakimś szablonie
  18.  
  19. foreach($model->getResults() as $item):
  20. // wyswietlanie wiersza
  21. endforoeach;
To nie kontroler odpowiedzialny jest za takie rzeczy jak ustawienie względem czego mają być sortowane wyniki czy która jest obecnie strona - to widok jest za to odpowiedzialny. Widok to nie tylko wyświetlanie danych (w MVP od tego jest ostatnia część - Presenter).
paxton
Odpowiem ci tylko na pytanie numer 5, reszta już ty chyba poprzednicy odpisali.

Kontroler, przynajmniej dla mnie jest najważniejszy, to on wszystkim steruje jak sama nazwa wskazuje, to on inicjuje modele, i wysyła dane z nich do widoku, tak przynajmniej ja to robię. CodeIgniter ma naprawdę bardzo fajny i prosty MVC wiec mógłbyś zaglądnąć w jego kod. Kontroler, również przetwarza wszystkie requesty od usera, i odpala poprawna akcje.
krzywy36
A jeśli akcją jest np. dodanie danych do bazy i nic nie trzeba wyswietlac tylko np. zrobić przekierowanie to kontroller wywołuje metody modelu, a potem robi przekierowanie?

Edit: Tak przy okazji, jaki framework jest idealnym przykladem implementacji MVC? snitch.gif
thek
Jeśli jest tylko dodanie to można by tak zrobić jak sugerujesz. Z tym, że usera wypadało by powiadomić czy operacja się powiodła czy nie winksmiley.jpg

Co do idealnej implementacji to nie ma. MVC jest rozumiane przez wielu różnie i ten najbardziej wzorcowy gdzie wszystko krąży między wszystkim ( idealny MVC to przekazywanie także danych między widokiem a modelem bez udziału kontrolera ) nie istnieje. Aczkolwiek jedna osoba tu pisząca na forum uważa, że jest taki... Poszperaj w temacie o MVC a sam zobaczysz.
Crozin
@thek: bo w środowisku webowym (ograniczonym protokołem HTTP) nie za bardzo jest możliwość stworzenia komunikacji widok -> model -> widok
Spawnm
a helpery/dekoratory to nie są modelami pracującymi w widoku ? smile.gif
Crozin
To musiałbyś jeszcze zdefiniować (albo podać przykład) takiego helpera/dekoratora (to ostatnie to już w ogóle nie wiem czym mogłoby być - w tym kontekście), ale generalnie w przypadku prawidłowej implementacji MVC to niemalże każdy model pracuje w widoku - tam ma to przede wszystkim robić.

Problemem środowiska webowego jest krótkotrwała żywotność. Chodzi o to, że każda akcja użytkownika (np. kliknięcie w przycisk) rozpoczyna cały proces od nowa (żądanie -> obsłużenie go (inicjalizowanie modeli/widoków/kontrolera) -> zwrócenie odpowiedzi), nie ma możliwości by po kliknięciu w przycisk ten wysłał do modelu jakieś dane, model po ich przetworzeniu poinformował widok, o tym, że zmienił swój stan, by widok mógł pobrać z niego dane i je wyświetlić - a to jest główna idea MVC. To dwie pierwsze literki odwalają całą robotę - trzecia im to w zasadzie tylko umożliwia.
Spawnm
No miałem na myśli np. model generowania formularzy czy dekorowania danych w tabelki , takie bajery przecież się robi w widoku winksmiley.jpg
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.