Rozumiem rolę modelu i widoku we wzorcu Model-Widok-Kontroler, ale trudno mi zrozumieć, dlaczego kontroler jest potrzebny.
Załóżmy, że tworzymy program szachowy wykorzystujący podejście MVC; stan gry powinien być modelem, a GUI powinien być widokiem. Czym dokładnie jest kontroler w tym przypadku?
Czy to tylko osobna klasa, która ma wszystkie funkcje, które zostaną wywołane, gdy, powiedzmy, klikniesz kafelek? Dlaczego nie wykonać całej logiki na modelu w samym widoku?
design-patterns
mvc
Anne Nonimus
źródło
źródło
Odpowiedzi:
Korzystając z twojego przykładu, kontroler zdecydowałby, co było legalnym posunięciem, czy nie. Kontroler poinformuje widok, jak ułożyć elementy na planszy podczas uruchamiania, korzystając z informacji otrzymanych od Modelu. Jest więcej rzeczy, którymi kontroler może się zająć, ale kluczem jest przemyślenie logiki biznesowej na tej warstwie.
Są chwile, w których wszystko, co robi Kontroler, to przesyłanie informacji tam i z powrotem, jak strona rejestracji. Innym razem Kontroler jest trudną częścią rozwoju, ponieważ na tej warstwie należy wykonać wiele czynności, takich jak na przykład egzekwowanie reguł lub wykonywanie skomplikowanej matematyki. Nie zapomnij o kontrolerze!
źródło
Kontroler to klej, który łączy model i widok razem, a także izolacja, która je rozdziela. Model nie powinien wiedzieć nic o widoku i odwrotnie (przynajmniej w wersji MVC firmy Apple). Kontroler działa jak adapter dwukierunkowy, tłumacząc działania użytkownika z widoku na komunikaty do modelu i konfigurując widok z danymi z modelu.
Użycie kontrolera do oddzielenia modelu i widoku sprawia, że kod jest bardziej przydatny do ponownego użycia, bardziej testowalny i bardziej elastyczny. Rozważ swój przykład szachowy. Model oczywiście obejmowałby stan gry, ale może również zawierać logikę, która wpływa na zmiany stanu gry, na przykład określanie, czy ruch jest legalny i decydowanie o zakończeniu gry. Widok wyświetla szachownicę i pionki oraz wysyła wiadomości, gdy element się porusza, ale nie wie nic o znaczeniu elementów, ruchu każdego elementu itp. Kontroler wie zarówno o modelu, jak i widoku, a także ogólny przebieg programu. Gdy użytkownik naciśnie przycisk „Nowa gra”, jest to kontroler, który mówi modelowi, aby utworzył grę, i używa stanu nowej gry do skonfigurowania planszy. Jeśli użytkownik wykona ruch,
Spójrz na to, co otrzymujesz, zachowując model i oglądaj osobno:
Możesz zmienić model lub widok bez zmiany drugiego. Być może będziesz musiał zaktualizować kontroler po zmianie jednego z nich, ale w pewnym sensie jest to jedna z zalet: części programu, które najprawdopodobniej ulegną zmianie, są skoncentrowane w kontrolerze.
Model i widok mogą być ponownie użyte. Na przykład możesz użyć tego samego widoku szachownicy z kanałem RSS jako modelu do zilustrowania znanych gier. Możesz też użyć tego samego modelu i zastąpić widok interfejsem internetowym.
Łatwo jest pisać testy zarówno dla modelu, jak i widoku, aby upewnić się, że działają tak, jak powinny.
Zarówno model, jak i widok często mogą korzystać ze standardowych części: tablic, map, zestawów, ciągów i innych kontenerów danych dla modelu; przyciski, kontrolki, pola tekstowe, widoki obrazów, tabele i inne dla widoku.
źródło
Istnieje wiele różnych sposobów realizacji tego ogólnego wzorca projektowego, ale podstawową ideą jest oddzielenie różnych problemów w razie potrzeby. MVC to ładna abstrakcja w tym sensie, że:
Model : Reprezentuje te dane, cokolwiek to może oznaczać
Widok : Reprezentuje interfejs użytkownika, cokolwiek to może znaczyć
Kontroler : Reprezentuje klej, który powoduje, że model i widok wchodzą w interakcję, cokolwiek to może znaczyć
Jest niezwykle elastyczny, ponieważ nie określa wiele. Wiele osób marnuje dużo przepustowości, argumentując szczegóły tego, co może oznaczać każdy element, jakie nazwy należy stosować zamiast nich i czy naprawdę powinny być 3, 2, 4 lub 5 komponentów, ale nie ma sensu pewien stopień.
Chodzi o to, aby oddzielić różne „części” logiki, aby się nie nakładały. Utrzymuj prezentację razem, trzymaj dane razem, logikę razem, komunikację razem. I tak dalej. Do pewnego stopnia, im mniej te obszary zainteresowania się pokrywają, tym łatwiej jest robić z nimi interesujące rzeczy.
To wszystko, czym naprawdę powinieneś się martwić.
źródło
Wszystkie dobre odpowiedzi do tej pory. Moje dwa centy to to, że lubię myśleć, że kontroler jest zbudowany przede wszystkim z pytaniami typu Co i gdzie?
dozwolone Nie jestem pewien, ale wiem gdzie i kogo zapytać (model).
Te małe fragmenty są przykładami tego, jak próbuję zapamiętać abstrakcję i koncepcję, którą MVC próbuje przekazać. Co, gdzie i jak są moje trzy główne procesy myślowe.
Co i gdzie => Kontroler Jak i kiedy => Modele i widoki
W gruncie rzeczy moje działania kontrolera wydają się być małe i zwarte, a podczas ich czytania czasami wyglądają jak strata czasu. Przy bliższej inspekcji działają one jako sygnalizator drogowy, kierując różne żądania do odpowiednich pracowników, ale nie wykonując żadnej z samych faktycznych prac.
źródło
Kontroler może pomóc w wyodrębnieniu interfejsów zarówno Widoku, jak i Modelu, aby nie musieli się o sobie bezpośrednio dowiedzieć. Im mniej obiekt musi wiedzieć, tym bardziej staje się przenośny i testowany jednostkowo.
Na przykład Model może odtwarzać inną instancję samego siebie przez jeden Kontroler. Lub kontroler sieciowy może połączyć ze sobą dwa obiekty Widoku gracza. Lub może to być test Turinga, w którym nikt nie wie, który.
źródło
To naprawdę wchodzi w grę, gdy masz do czynienia z procedurami obsługi zdarzeń, ale nadal potrzebujesz kontrolera do obsługi interakcji między widokiem a modelem. Idealnie nie chcesz, aby widok wiedział coś o modelu. Pomyśl o tym, czy chcesz, aby jsp bezpośrednio nawiązywał wszystkie połączenia z bazą danych? (Chyba że jest to coś w rodzaju wyszukiwania przy logowaniu). Chcesz, aby widok renderował dane i nie posiadał żadnej logiki biznesowej, chyba że jest to logika wyświetlania, ale nie logika biznesowa.
W GWT uzyskasz czystszą separację dzięki MVP. W widoku nie ma żadnej logiki biznesowej (jeśli jest to zrobione prawidłowo). Prezenter działa jako kontroler, a widok nie ma wiedzy o modelu. Dane modelu są po prostu przekazywane do widoku.
źródło
Widok dokumentu (tj. Widok modelu) jest standardowym modelem dla większości aplikacji Windows napisanych w MFC, więc musi działać w wielu przypadkach.
źródło
Jesteś tego pewien? (Przynajmniej tak, jak pierwotnie opisano) Celem modelu jest model domeny. Widok ma wyświetlać model domeny użytkownikowi. Kontroler ma odwzorować wejście niskiego poziomu na mówienie modelu wysokiego poziomu. O ile mogę stwierdzić, uzasadnienie jest następujące: A) użycie SRP na wysokim poziomie. B) Model został uznany za ważną część aplikacji, więc trzymaj z niego nieważne i szybciej zmieniające się rzeczy. C) łatwo testowalna (i skryptowa) logika biznesowa.
Pomyśl tylko, czy chcesz, aby Twój program szachowy był użyteczny dla osób niewidomych, zamień widok na słyszalną wersję i kontroler współpracujący z klawiaturą. Powiedz, że chcesz dodać gry pocztą, dodaj kontroler, który akceptuje tekst. Wersja netto gry? Kontroler wykonujący polecenia z gniazda wykonałby zadanie. Dodaj do niego ładny render 3d, nowy, fajny widok. Niezbędne zmiany modelu zerowego Szachy są nadal szachami.
Jeśli pomieszasz dane wejściowe z reprezentacją modelu, utracisz tę zdolność. Nagle szachy to nie szachy, to szachy z myszką, które różnią się od szachów z klawiaturą lub połączeniem sieciowym.
źródło
Myślę, że MVC jest głupi, może w niektórych obszarach działa dobrze, ale osobiście nawet strony internetowe, które piszę, nie są odpowiednie dla mvc. Istnieje powód, dla którego słyszysz frontend, backend i nigdy nie koniec bazy danych lub coś innego
IMO powinien mieć API (backend) i aplikację, która korzysta z API (frontend). Wydaje mi się, że można wywołać żądanie GET kontrolerem (który po prostu wywołuje interfejs API zaplecza), a HTML - widok, ale zwykle nie słyszę, aby ludzie mówili o widoku jako czystym HTML ani modelu będącym interfejsem API zaplecza.
IMO wszystko powinno być solidnym API. W rzeczywistości nie muszą być solidne (jak w czystym i dobrze zbudowanym), ale jego elementy wewnętrzne powinny pozostać prywatne, a aplikacja / frontend / poza interfejsem API nigdy nie powinna mówić o połączeniu z bazą danych ani nie może wykonywać surowych zapytań.
Teraz, jeśli twój kod / projekt wymaga klejenia, to dobrze. Jeśli w twojej grze w szachy jest jakiś znacznik, który możesz edytować, aby skórować GUI, GUI zbiera współrzędne / dane wejściowe i wywołuje MovePiece (srcPosition, dstPostion) (co może zwrócić wartość bool lub enum, aby powiedzieć, czy jest to poprawny ruch, czy nie ) i nie ma problemu z logiką zawartą w modelu, więc na pewno nazwij to MVC. Nadal jednak organizuję rzeczy według klas i interfejsów API i upewniam się, że nie ma klasy zlewu kuchennego, która dotykałaby wszystkiego (ani żadnych interfejsów API, aby wiedzieć o wszystkim).
źródło
Pomyśl o przeglądarce, która wyświetla statyczną stronę internetową. Model to HTML. Widok to rzeczywisty wynik na ekranie.
Teraz dodaj trochę JavaScript. To jest kontroler. Gdy użytkownik kliknie przycisk lub przeciągnie coś, co Zdarzenie zostanie wysłane do JavaScript, decyduje o tym, co należy zrobić, i zmienia bazowy HTML (Model), a przeglądarka / renderer wyświetla te zmiany na ekranie (Widok).
Być może kliknięto inny przycisk, zdarzenie jest wysyłane do jakiegoś modułu obsługi (kontrolera) i może powodować żądanie wysłania dalszych danych do usługi internetowej. Wynik jest następnie dodawany do HTML (Model).
Kontroler reaguje na zdarzenia i kontroluje to, co jest w Modelu, a tym samym to, co jest na ekranie / Widoku.
Cofając się nieco, możesz myśleć o całej przeglądarce jako widoku, a serwerze jako kontrolerze, a danych jako o modelu. Gdy użytkownik kliknie przycisk w przeglądarce zdarzenia wysłanego na serwer (kontroler), gromadzi zasoby jako stronę HTML (model) i wysyła je z powrotem do przeglądarki, aby je wyświetlić (widok)
Na dole serwera, niezależnie od tego, czy jest to asp, php czy java, „kod” (kontroler) odbiera zdarzenie click i odpytuje bazę danych lub repozytorium dokumentów (model) i tworzy HTML. Z punktu widzenia serwera wynikiem wszystkich jego działań jest Widok (HTML) bazowego magazynu danych (Model). Ale z punktu widzenia klienta wynikiem jego żądania do serwera jest model (HTML)
Nawet jeśli zbierzesz JavaScript w HTML lub PHP w HTML, model, widok, kontroler nadal istnieje. Nawet jeśli myślisz o swojej prośbie do serwera i odpowiedzi z serwera jako prostej dwukierunkowej ulicy, nadal istnieje Model, Widok i Kontroler.
źródło
Z mojego doświadczenia wynika, że w tradycyjnym programie GUI mvc na pulpicie kontroler jest spaghetti. Większość ludzi nie poświęca czasu na wyróżnienie klasy kontrolera.
książka o gangach czterech mówi:
źródło