Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MVC] Rozbudowany router i wyspecjalizowane kontrolery?
Forum PHP.pl > Forum > PHP > Object-oriented programming
MacDada
Hej,

mam dwa koncepty na pisanie aplikacji, ale właściwie to oba mi nie podchodzą pod gust.

Koncept 1: Rozbudowany router i wyspecjalizowane kontrolery.
Wygląda to tak, że router pobiera sobie PATH_INFO, rozbija na tablice i interpretuje co jest kontrolerem, co akcją, co innymi parametrami. Odpala więc odpowiedni kontroler i przekazuje mu tablicę z ustaloną akcją i parametrami.

Koncept 2: Mały router, rozbudowane i „inteligentne” kontrolery.
Router pobiera sobie PATH_INFO, rozbija na tablice, rozpoznaje pierwszy parametr jako kontroler i odpala go, przekazując mu surową tablicę. Dopiero kontroler ma swój mini-router, który rozpoznaje co jest akcją, co parametrem i na tej podstawie działa.

Które rozwiązanie jest lepsze?

Kolejne pytanie. Chciałbym, żeby aplikacja była możliwie bardzo zmodularyzowana, a więc, żeby można było wziąc klocki i na ich podstawie zbudować stronę. Takimi klockami byłby moduł menu, moduł newsów, moduł kalendarza, księgi gości, moduł reklamy, itd. Każdy moduł miałby swój kontroler i zestaw widoków. Czyli działanie aplikacji wyglądałoby tak:

Chcę wyświetlić stronę z newsem, to odpalam kontroler newsów, który zajmuje się wyświetleniem newsa. Oprócz tego odpalam kontroler menu i kontroler reklamy. Każdy to niezależny klocek, który można wykorzystać na dowolnej stronie. Już o tym kiedyś pisałem.

Jak jednak to zrealizować? Musiałbym kontrolerowi newsów w odpowiednim momencie kazać wyświetlić to menu, czyli kontroler musiałby albo mieć metodę render (czyli zajmować się aspektami widoku) albo zwracać w zmiennej gotowy kod HTML, który wyświetlałby dopiero kontroler, który wywołał moduł tworzenia menu...

No kolejna sprawa.

Mam np http://strona.com/news/4/
Czyli strona odpala kontroler News, akcja domyślna View, parametr 4 jako identyfikator newsa.

Z drugiej strony mam panel admina: http://strona.com/admin/news/4/edit/
Czyli strona odpala kontroler admin, ten odpala kontroler news, itd.

Czy powinienem zrobić dwa oddzielne kontrolery - jeden "kliencki" tylko z opcją wyświetlania, drugi adminowy, z edycją, itd. - czy może jeden kontroler „inteligentny”, który w zależności od kontekstu inaczej się zachowuje?


Dzięki za odpowiedzi, ostatnio więcej siedzę i myślę nad koncepcją pisania niż rzeczywiście spędzam czas na kodowaniu... sciana.gif
Crozin
Co do routera: opcja #1 - czyli "rozbudowany router" - jeżeli jakiś parametr będzie na tyle "skomplikowany", że router nie będzie mógł sobie z nim poradzić (chociaż nie za bardzo wiem gdzie mogła by taka sytuacja zaistnieć) może przekazać go w surowej formie kontrolerowi - niech się nią zajmie.
Co do samej architektury: to co opisujesz brzmi jak HMVC.
Co do "inteligentnego kontrolera": dwa kontrolery, bo to dwie różne rzeczy... zresztą kontroler jest na tyle prostym elementem, że nie przybędzie Ci wiele kodu z tego faktu, a całość będzie łatwiej utrzymać w kupie.
Pilsener
1. Router vs controller - router to router, sam sobie odpowiedziałeś, router ma zwrócić tablicę parametrów i dołączyć ją do rejestru czy czego tam używamy by mieć łatwy dostęp do zmiennych, kontroler nie powinien zajmować się obróbką adresów typu index,34.html, bo pogubimy się w logice aplikacji, tablica parametrów powinna wynikać jasno z routingu.

2. Masz coś takiego jak LAYOUT, lub "drzewo widoków", każdy szablon może się składać np. z:
  1. <p>{pogoda}</p>
- a zmienna pogoda może zawierać kolejny layout, obiekt, szablon, zwykły html lub liczbę. Przy strukturalnym realizowałem to tak, że dla każdego modułu/kontrolera/akcji była podpięta tablica modułów, które należało zaincludować i te includowane bajery dodawały swoje zmienne do przypisanego do tego adresu szablonu. Możesz w widoku strony głównej wywołać kontroler news:
  1. $this->action(array('action'=>'view','module'=>'news','controller'=>'index'));


3.
Cytat
Czy powinienem zrobić dwa oddzielne kontrolery - jeden "kliencki" tylko z opcją wyświetlania, drugi adminowy, z
edycją, itd. - czy może jeden kontroler „inteligentny”, który w zależności od kontekstu inaczej się zachowuje?
- do wyświetlania newsów jeden kontroler, a do adminowania (back office) drugi, kontroletry bym podzielił na poszczególne akcje, oprócz kontrolerów i akcji dodałbym jeszcze moduły. Oczywiście czasem są elementy wspólne, mniej lub więcej - podział aplikacji na moduły/kontrolery/akcje musi to uwzględniać.

Ja bym Ci radził skorzystać z frameworków i zobaczyć, jak tam się to odbywa, nie ma sensu popełniać czyichś błędów.
LBO
Cytat(MacDada @ 20.08.2010, 21:41:24 ) *
Koncept 1: Rozbudowany router i wyspecjalizowane kontrolery.[/b]
Wygląda to tak, że router pobiera sobie PATH_INFO, rozbija na tablice i interpretuje co jest kontrolerem, co akcją, co innymi parametrami. Odpala więc odpowiedni kontroler...


Stop, router nic nie odpala. Istnieje taka zasada. która mówi, że obiekty powinny mieć jak najmniejszą odpowiedzialność (zdaje się, że dokładnie jedną biggrin.gif).
Tak więc zostaw routerowi zabawę z deszyfrowaniem URLa, a samo odpalenie akcji przekaż do innego obiektu.
Luneth
Odpalać powinien IMHO Front Controller chociażby najprostszy (takie chyba w sumie są najlepsze biggrin.gif) a tak jak przedmówca napisał - router to router i ma swoje zadanie, czyli parsowanie urla.
Crozin
@Luneth: a co ma Front Controller do odpalania akcji? Poza tym nawet nie wiemy czy autor wątku ma zamiar skorzystać z Front Controllera. Od tego jak już jest Dispatcher.
Luneth
Chodziło mi, że front controller "odpala" odpowiedni kontroler - nie akcję. Wybacz mój brak precyzji winksmiley.jpg A swoich akcji czasem kontrolery nie odpalą?
MacDada
Dzięki za odpowiedzi. Na razie swój projekt wstrzymałem i poszedłem za radą Pilsenera - poznaję teraz symfony. Z tego co widzę chyba rzeczywiście nie ma sensu na nowo koła odkrywać smile.gif


EDIT:
BTW, forum niepoprawnie interpretuje dywizy (takie jakby myślniki). Zamienia je na znaki zapytania. Przykład: ?
dariuszp
Wprowadź w swoją aplikację dodatkową warstwę usług. Jak wyżej Ci dobrze poradzono - daj Cezarowi to cezara a bogu to co do boga należy. Inaczej rzecz mówiąc - Router niech zajmie się routingiem i niczym innym. Jak to działa w praktyce ?
W URL albo innym sposobem (widziałem zastosowanie gdzie przekazywane parametry były z tablicy $_SERVER) przekaż usługę z jakiej korzystasz. Po co usługa ? A no np nie trzeba inicjalizować całego systemu kiedy użytkownik sięga ajaxem po jeden moduł. Tak samo nie trzeba tego robić jak użytkownik sięga po jakiś zabezpieczony plik. Ładujesz usługę która ładuje MINIMUM potrzebnych informacji (np dane użytkownika i prawach dostępu do zasobu). Standardowa usługa (ja z natury zwę ją public, moj kolega po fachu używa "default", co kto woli) ładuje pełną stronę.

Tutaj już do pracy wchodzi router. Jest on odpowiedzialny za analizę URL'a. Tutaj jego zadanie polega TYLKO na zidentyfikowaniu usługi i uruchomieniu jej. Po czym przekazuje usłudze kontrole.

Gdy usługa zostaje uruchomiona znowu wywołujemy Router prosząc o parametry specyficzne dla danej usługi, bierzemy się za załadowanie informacji o użytkowniku i stronie którą wywołał. Dopiero tutaj uzupełniane są uprawnienia użytkownika (bo różne usługi mogą korzystać z różnego zestawu uprawnień), informacje o stronie (np jakie moduły się na niej pojawią) i jaką akcję użytkownik wywołuje (a może wysłał formularz stronę szybciej).

W tym momencie ładujesz widok i moduły. Ja osobiście na tym etapie troszkę namieszałem.

Nie mniej jednak wcześniej ładujemy widok i sprawdzamy czy wszystko jest OK (czy struktura strony się zgadza, czy pliki są na miejscu, czy uprawnienia są ok). Jeżeli wszystko jest gotowe, ładuję kolejno moduły i wykonuję je. Te zwracają mi sparsowany kod HTML (korzystam smarty i cieszę się z możliwości metody fetch() która jest tam obecna). i zbieram kod HTML po widoku który następnie wysyłam do zmiennej szablonu (moduły mają własne pliki szablonu które mogą być nadpisane przez szablon strony) i uzupełniam stronę.

Tak przygotowana strona zostaje wyświetlona. Mam możliwość kontrolowania w którym miejscu co się pojawi, czy się pojawi, jak się pojawi itp. Dodatkowo sam proces jest dość prosty i przejrzysty. No i jak na razie żaden programista który miał do czynienia z moim kodem nie narzekał.

To tak w skrócie.
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.