Technologie i narzędzia: język PHP 5, Java, JavaScript, Python, system Zend Framework, Django, biblioteka jQuery, Smarty, platforma Eclipse, MySQL, SVN, CVS, UML, Firefox.
WebProgramming - wszystko o serwisach internetowych
O serwisach internetowych.
[php] Wzorzec MVC
O korzyściach wykorzystywania wzorca MVC w aplikacjach internetowych (i nie tylko) nie muszę mówić - to nie podlega dyskusji. Jego definicja nie określa jednak dokładnie jak należy go zaimplementować, w związku z czym możliwości realizacji tego wzorca są duże - nawet w miejscach, które wydawałoby się bez znaczenia. Zapraszam do krótkiego omówienia tej kwestii.
Jak wiadomo wzorzec MVC polega na oddzieleniu trzech warstw aplikacji (akcji, modelu i widoku), tak aby zminimalizować propagacje zmian, w przypadku dokonywania modyfikacji w jednej z tych warstw. Ogólnie wygląda to mniej więcej tak (patrz też Wikipedia):
- żądanie jest przekazywane do skryptu/klasy/metody (przez tak zwany FrontController), która jest odpowiedzialna za jego realizacje (kontroler)
- w kontrolerze następuje odwołanie do modelu (w skrócie mówiąc do bazy danych)
- w kontrolerze inicjowane są również “zmienne”, które zostaną przekazane do widoku
- widok wyświetla HTML (lub inny format) na podstawie “zmiennych” z kontrolera
W dalszej części moich wywodów założę (dla ułatwienia), iż podstrony (moduły) w naszym serwisie różnią się od siebie tylko treścią główną - pozostałe elementy pozostają bez zmian. Tak więc będziemy rozróżniać szablon główny (czyli całego serwisu, zawierający stopkę, nagłówek, itp) oraz szablon modułu (czyli szablon odpowiedzialny za wyświetlanie treści).
Poniżej przedstawię dwa podejścia do MVC na pierwszy rzut oka tylko trochę różniące się od siebie - jednak “trochę” robi wielką różnice.
Opis i przykłady oprę tym razem na jednym z najczęstszych systemów wykorzystywanych w aplikacjach PHP - system szablonów Smarty (więcej informacji o systemie Smarty znajduje się na stronie http://smarty.php.net/). System służy głównie do oddzielenia kodu PHP od kodu HTML, co jest głównym założeniem wzorca MVC.
Opcja I: Jeden ze sposobów budowania serwisów w oparciu o ten system jest stworzenie szablonu głównego, w którym będziemy ładować szablony modułu, w postaci:
-
<!– naglowek strony –>
-
{include file="$module.tpl"}
-
<!– naglowek strony –>
Wtedy w akcji (PHP) do zmiennej $module przypisujemy nazwę szablonu dla żądanej treści . Zwróć uwagę, że w tym momencie pierwszy zostaje wykonany szablon główny, a dopiero później szablon modułu.
Opcja II. Ten sam problem możemy rozwiązać inaczej generując stronę HTML na początku dla podszablonu, a później dla szablonu głównego. Wówczas szablon główny wyglądałby następująco:
-
<!– naglowek strony –>
-
{$pageContent}
-
<!– naglowek strony –>
Natomiast w kodzie PHP istniałby zapis, pobierający kod szablonu modułu:
-
$smarty->assign(‘pageContent’, $smarty->fetch($module.‘.tpl’));
Wspomnianą wcześniej różnicą jest właśnie kolejność wykonywania szablonów, przy czym korzystniejsza wydaje się być druga opcja (chociaż sam przez długi czas używałem pierwszej). Głównie dlatego, iż w tej opcji możemy w szablonie modułu umieścić kod ładujący (np za pomocą wtyczki) dodatkowe style lub/i pliki JavaScript. W pierwszej opcji było to nie możliwe, ponieważ nagłówek strony HTML jest wyświetlany wcześniej niż szablon modułu.
Zdaje sobie sprawę, iż Ameryki nie odkryłem
Jednak nie zawsze i nie każdy od razu widzi tą różnice, co skutkuje często instrukcjami {if ..} wyświetlającymi warunkowo style w zależności od modułu. Korzystając z opcji drugiej możemy również dodawać instrukcje modyfikujące inne fragmenty szablonu głównego (na przykład <title></title>) - uzyskujemy w ten sposób łatwy i przyjemny sposób generowania widoku.
Zaznaczam od razu, iż przedstawione rozwiązania mają prawo bytu tylko w prostszych serwisach, w bardziej skomplikowanych należy je odpowiednio rozbudować. Idea jednak pozostaje ta sama.
Przy okazji chciałem wspomnieć o MVC w trochę innym podejściu (tak zwany Model 2). Mimo, iż jest on rzadko używany w serwisach internetowych można go spotkać w niektórych rozwiązaniach. Na przykład biblioteka Zend_Form (obsługa formularzy w systemie Zend Framework) korzysta z tego modelu. Rezultatem korzystania z tego rozwiązania jest budowanie kod HTML za pomocą obiektów i ich atrybutów, na przykład:
-
$form = new Zend_Form();
-
$form->setAttrib(‘id’, ‘login’);
-
$form->addElement(‘text’, ‘username’);
Osobiście uważam jednak, iż nie jest dobrą praktyką mieszanie tych dwóch podejść (czyli MVC Model 1 i Model 2) w jednym miejscu, tym bardziej, iż taki sam rezultat można uzyskać za pomocą odpowiednio zbudowanych wtyczek (plugins, helpers). Jednocześnie biorąc pod uwagę możliwości twórcze grafików śmiem powiedzieć, iż bardziej elastycznym i eleganckim rozwiązaniem jest właśnie generowanie widoku za pomocą wtyczek. Przy okazji zachęcam do zapoznania się z moją biblioteką do obsługi formularzy Fasic_Form.
Napisz komentarz