![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 45 Pomógł: 0 Dołączył: 15.09.2008 Ostrzeżenie: (0%) ![]() ![]() |
Witam,
uprzedzam, że przeczytałem temat przypięty wraz z odnośnikami i niewiele mi to pomogło - niestety. Mam trzy pytania odnośnie tego wzorca - jeżeli tworzę aplikację web'ową, to: 1. Czy kontroler jest samym plikiem (index.php), czy dopiero plik główny go inicjuje? 2. Jak jest z widokiem? Czy HTML jest zwracany do kontrolera, czy do pliku głównego? (przy opcji, że kontroler trzeba wcześniej załączyć) 3. Czy widok jest załączany przez kontroler, czy przez plik główny? (również przy drugiej opcji) |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 952 Pomógł: 154 Dołączył: 20.01.2007 Skąd: /dev/oracle Ostrzeżenie: (0%) ![]() ![]() |
Mniej więcej właśnie o to chodzi. Architektura MVC dla aplikacji WWW (tzw. Model 2) wygląda następująco. Mamy dwa scenariusze:
Użytkownik chce coś zobaczyć Kontroler: - Sprawdza, co zrobił użytkownik - Wybiera odpowiedni widok - Wybiera odpowiedni model - Informuje widok, z jakiego modelu będzie korzystać. Model - Pobiera dane na żądanie widoku Widok - Decyduje o tym, jak wyświetlić dane - Pobiera interesujące go dane z modelu - Zajmuje się obsługą logiki wyświetlania - Wyświetla wszystko Użytkownik chce coś zmienić (formularz) Tutaj w stosunku do klasycznego MVC jest taka modyfikacja, że dane przychodzą do nas w żądaniu HTTP jako pewne zadanie dla kontrolera. Kontroler - Sprawdza, co użytkownik zrobił. - Wybiera model. - Wybiera widok, jeśli potrzeba, albo robi redirect, co technicznie oznacza, że inny kontroler rozpoczyna pracę. - Pobiera dane i przekazuje je do modelu z żądaniem zmiany stanu (czyli np. aktualizacja danych w bazie). - Informuje widok, z jakiego modelu ma korzystać. Model - Zmienia swój stan, czyli dokonuje aktualizacji informacji. - Udostępnia dane. Widok Nie ma bata, w HTTP albo robimy przekierowanie, czyli skaczemy do innego kontrolera, albo musimy coś wyświetlić, dlatego widok dalej działa tak samo. Zasadniczo w klasycznym MVC wmieszany jest jeszcze wzorzec obserwatora na wypadek, gdyby model samoistnie zmienił stan (wtedy może on powiadomić widok, że coś się zmieniło i trzeba odświeżyć ekran), jednak w WWW nie ma to żadnego sensu praktycznego ze względu na budowę protokołu HTTP, dlatego się to pomija. Zauważmy też, że część komunikacji między komponentami realizowana jest za pomocą wywołań odpowiednich metod, a część (np. widok informuje kontroler, że coś się stało) realizowana jest za pomocą żądań HTTP. Dodatkowo należy pamiętać jeszcze o dwóch kretynizmach popełnianych we frameworkach: - Zrównanie modelu z ORM-em. ORM może być wykorzystywany przez model, ale nie może być modelem, bo nie i koniec. Model ma stanowić abstrakcyjny interfejs dostępowy tak, by aplikacja nie musiała się zajmować tym, czy dane idą z bazy czy z plików czy z czegoś innego. Tymczasem we współczesnych frameworkach z technicznego punktu widzenia jeśli będziemy chcieli coś pobrać z czegoś innego niż baza, to pozbawiamy się modelu. Przykład problemu, który to powoduje: mamy jakieś teksty informacyjne wyświetlane w różnych miejscach strony, które zapisane są na sztywno w jakimś pliku. Aplikacja jest rozbudowywana, pojawia się możliwość wprowadzania artykułów i klient chciałby, by w ramach tego mógł też edytować te statyczne teksty. I nagle okazuje się, że zmienia się wewnętrzna reprezentacja danych, a my żeby ją uwzględnić, zmieniamy... kontroler. - Zrównanie szablonów i systemów szablonów z widokiem. No hola hola, a gdzie logika prezentacji? Przecież jak mamy np. stronicowanie, to gdzieś musimy je także skonfigurować, coś się musi zająć obsługą techniczną tego stronicowania, ale ponieważ widok jest szablonem, kod leci do... kontrolera. Coś tu nie gra, kontroler przecież nie powinien zajmować się tym, jak dane są prezentowane, a według mnie obecność stronicowania to specyfika ustaleń między widokiem, a modelem. Poniżej przykład, jak można w takim modelu MVC zbudować coś fajnego. Przyjrzyjmy się CRUD-owi, czyli klasycznemu zestawowi operacji bazodanowych. Mamy listy elementów: newsy, artykuły, użytkowników itd. W "pseudo-MVC" głoszonym przez współczesne frameworki PHP tzw. "szybkość i prostotę tworzenia" uzyskuje się nie za pomocą "pseudo-MVC", tylko narzędzia konsolowego, które automatycznie generuje nam 483827834738 plików, po jednym dla każdej tabeli i które potem musimy ręcznie wypełniać. Tymczasem w prawdziwym MVC możemy zastosować takie podejście: - Tworzymy widok ListView, który pobiera dane z modelu, opakowuje je w listę, dodaje sortowanie po kolumnach i stronicowanie. - Autorytarnie stwierdzamy, że widok ListView może współpracować z modelami implementującymi interfejsy Listable, Sortable, Paginable, ListDefinitions - Za pomocą zawartych w tych interfejsach metod widok pobiera z modelu listę elementów, pobiera informacje o tym, które elementy można sortować, przekazuje informacje o tym, jaka strona wyników go interesuje, zaś przy pomocy ListDefinitions może ściągnąć informacje o tym, jak np. zatytułować kolumny, jak nazywają się wyświetlane byty itd. - Tworzymy 298373 modeli implementujących te interfejsy, każdy pobiera dane ze swojej tabelki i odpowiednio reaguje na wywołania metod w tych czterech interfejsach. Różnica jest kolosalna. Jeśli w takim Zend Frameworku czy innym nagle stwierdzimy, że chcemy wzbogacić interfejs o np. wyszukiwanie, jesteśmy w d..., bo musimy to dopisać z osobna do każdego kontrolera, każdego modelu i każdego widoku dla każdej tabeli. Tutaj dodajemy kolejny interfejs, zmieniamy JEDEN widok, a reszta to poprawki w modelach. O ileż mniej roboty? O ileż większa zgodność z zasadami projektowania obiektowego? Powiem nawet więcej - widok może być inteligentny i posprawdzać sobie, jakie interfejsy implementuje model i na podstawie tego decydować: "aaa, ten model nie implementuje Paginable, więc oznacza to, że tu nie ma być stronicowania". I nagle okazuje się, że możemy diametralnie zmienić funkcjonalność, po prostu dodając lub zabierając interfejsy z modeli. Oczywiście jak piszemy front-end i sztywne ramy mechanizmu CRUD nam nie pasują, musimy napisać inne widoki do konkretnych zastosowań, ale w wielu przypadkach nawet te konkretne zastosowania są na tyle ogólne, że można stworzyć jeden widok pasujący do kilku miejsc i sytuacji. Tak się składa, że robiłem niedawno aplikację w PHP opartą o prawdziwy wzorzec MVC i to, co serwują nam frameworki, nawet do pięt mu nie dorasta. Ironią jest, że jedyny znany mi skrypt poprawnie implementujący MVC to... Joomla. I to jest chyba jedyna dobra rzecz, jaką można powiedzieć o jej kodzie. Jakby ktoś jeszcze nie dowierzał, to podaję pierwszą z brzegu książkę prezentującą właśnie taki sposób działania MVC w aplikacjach WWW, z widokiem komunikującym się bezpośrednio z modelem: Head First Design Patterns, strony 567-575. Ten post edytował Zyx 5.02.2010, 16:56:54 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 14.10.2025 - 21:01 |