Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MVC] Widok a kontroler
Forum PHP.pl > Forum > PHP > Object-oriented programming
l0ud
Cześć

Będę bardzo wdzięczny, jeżeli znajdzie się ktoś, kto nie przerazi od razu się rozmiarem postu i postanowi go przeczytać winksmiley.jpg

Od dłuższego czasu staram się budować aplikacje w MVC, dotychczas były proste i widoki w nich i działały chyba na zasadzie podobnej jak w Kohanie - po prostu kontroler pobierał dane z modelu i tworzył obiekt(y) widoku w których je obsadzał. Sam widok był po prostu szablonem - opakowanym w klasę która umożliwiała umieszczanie zmiennych, przetworzenie tego szablonu i zwrócenie wyniku. Kontroler decydował o tym, jakie szablony (widoki) mają być wczytane. To rozwiązanie było proste i sprawdzało (sprawdza) się w mniejszych projektach.

W tej chwili potrzebuję jednak większej elastyczności i trochę błądzę sad.gif Założenie jest takie: widok musi być wymienialny i oferować prawie nieograniczone możliwości modyfikacji. Na przykład, na stronie głównej ma być widoczne logo i górne menu, zaś powiedzmy na stronie modyfikacji profilu już nie. Wiem, że przykład jest głupi, jednak pokazuje o co mniej-więcej mi chodzi. Poprzednie rozwiązanie by się nie sprawdziło - kontroler wczytałby z góry przygotowane pliki szablonu dla danej akcji (szkielet strony, logo), zmienić mógłbym jedynie środek.

Rozwiązanie które wymyśliłem wyglądałoby tak:
- Użytkownik wchodząc na serwis wywołuje plik index.php. Plik ten wczytuje front controller'a i nakazuje mu wczytać akcję (bezpośredni kontroler)
  1. <?php
  2. //dołączanie niezbędnych plików
  3. try {
  4. $fbCore = new fbCore;
  5. $fbCore->loadDirectController($fbCore->Request->getVar(0));
  6. }
  7. //wyłapywanie błędów
  8. ?>


- Front controller (fbCore) zajmuje się wczytywaniem wszystkich potrzebnych klas i tworzeniem ich instancji. Pełni rolę pośrednika pomiędzy nimi i sam je przechowuje (czyli jest też rejestrem). W tym przypadku wczytuje i tworzy bezpośredni kontroler (akcję) przekazując jej swoją instancję - daje jej więc prawa do wczytywania modeli, kontrolerów i widoków.
Tutaj zaczyna się problem. Jeżeli akcja ma polegać na samej modyfikacji danych, no to jest prosto. Informacje od użytkownika pobiera od modelu Request (jego instancję ma od fbCore), wczytuje odpowiedni model i zleca mu zamianę danych. Gorzej jeżeli jest to np. akcja wyświetlenia strony głównej. W takim przypadku akcja nakazuje fbCore wczytać widok 'mainPage', a następnie go wyświetla. To wszystko.
Widok utworzony przez fbCore otrzymuje jego instancję. Może więc wczytywać dowolne obiekty. TUTAJ TKWI PROBLEM, ponieważ jest w nim właściwie istota całej akcji.
Najprostszym sposobem byłoby teraz pobranie w widoku instancji odpowiednich modeli (za pomocą otrzymanego fbCore), następnie pobranie z nich danych i wyświetlenie. Może też wczytywać inne widoki i łączyć je ze sobą - np. widok menu, który sam wczytuje sobie jakiś model i pobiera z niego dane, widok 'domyślnej' strony - który pobiera inne widoki (menu, logo itp.)

Co mi się nie podoba w tym sposobie:
- widok bezpośrednio operuje na modelu i pobiera z niego dane. Oczywiście, kwestie ich modyfikacji zostawiłbym kontrolerowi.
- cała istota akcji 'starego sposobu' (opisałem go na początku) zostaje przeniesiona do widoku, przez co ta akcja ma najczęściej co najwyżej kilka linijek kodu.
- widok może wczytywać modele, kontrolery i inne widoki (za pomocą fbCore) - czy to nie za dużo wpływu na działanie aplikacji?

Moje pytanie brzmi, czy faktycznie sposób jest niezgodny z ideą MVC i do bani, czy po prostu jestem przewrażliwiony? A może dałoby by się to rozwiązać jakoś lepiej, prościej albo bardziej poprawnie? smile.gif

Pozdrawiam
erix
Cytat
W tej chwili potrzebuję jednak większej elastyczności i trochę błądzę Założenie jest takie: widok musi być wymienialny i oferować prawie nieograniczone możliwości modyfikacji. Na przykład, na stronie głównej ma być widoczne logo i górne menu, zaś powiedzmy na stronie modyfikacji profilu już nie. Wiem, że przykład jest głupi, jednak pokazuje o co mniej-więcej mi chodzi. Poprzednie rozwiązanie by się nie sprawdziło - kontroler wczytałby z góry przygotowane pliki szablonu dla danej akcji (szkielet strony, logo), zmienić mógłbym jedynie środek.

W widoku możesz jeszcze wydzielić miejsce na szablon...

Cytat
Moje pytanie brzmi, czy faktycznie sposób jest niezgodny z ideą MVC i do bani, czy po prostu jestem przewrażliwiony? A może dałoby by się to rozwiązać jakoś lepiej, prościej albo bardziej poprawnie?

A KISS? Nie zawsze utarte wzorce są ok - ile było starć, czy singleton, czy registry... Póki aplikacja działa w porządku, jesteś w stanie wprowadzać do niej zmiany i wszystko ma swoje miejsce - rozwiązanie jest dobre. I wcale nie musi być MVC; przecież nie wszystkie samochody mają manualną skrzynię biegów. winksmiley.jpg

Cytat
np. widok menu, który sam wczytuje sobie jakiś model i pobiera z niego dane, widok 'domyślnej' strony - który pobiera inne widoki (menu, logo itp.)

Chyba w ZF jakoś wykorzystano koncepcję subView, możesz się spróbować wzorować.
megawebmaster
A nie łatwiej byłoby dodać możliwość nie dziedziczenia po szkielecie strony i wykonaniu po prostu osobnego szablonu? I niech kontroler decyduje co ma się dziać, a nie widok. Tyle chyba?
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.