Pytanie Czym są MVP i MVC i jaka jest różnica?


Patrząc poza RAD (przeciągnij i upuść i skonfiguruj) sposób budowania interfejsów użytkownika, który wiele narzędzi zachęca, może natknąć się na trzy wzorce projektowe zwane Kontroler widoku modelu, Model-widok-prezenter i Model-View-ViewModel. Moje pytanie składa się z trzech części:

  1. Jakie problemy dotyczą tych wzorców?
  2. Jak są podobne?
  3. Czym się różnią?

1839
2017-08-05 10:06


pochodzenie


mvc.givan.se/#mvp - givanse
IDK, ale podobno do oryginalnego MVC, miał być używany w małych. Każdy przycisk, etykieta itp. Miał swój własny widok i obiekt kontrolera, a przynajmniej tak twierdzi wuj Bob. Myślę, że mówił o Smalltalk. Spójrz na jego rozmowy na YouTube, są fascynujące. - still_dreaming_1
MVP dodaje dodatkową warstwę pośrednią, dzieląc kontroler widoku na widok i prezenter ... - the_prole
Główna różnica polega na tym, że w MVC kontroler nie przekazuje żadnych danych z modelu do widoku. Po prostu powiadamia widok, aby pobrać dane z samego modelu. Jednak w MVP nie ma połączenia między widokiem a modelem. Sam prezenter pobiera wszelkie potrzebne dane z Modelu i przekazuje je do Widoku do pokazania. Więcej na ten temat wraz z próbką Androida we wszystkich wzorcach architektury jest tutaj: digigene.com/category/android/android-architecture - Ali Nem


Odpowiedzi:


Model-widok-prezenter

W MVPprezenter zawiera logikę biznesową interfejsu użytkownika dla widoku. Wszystkie inwokacje z widoku delegują bezpośrednio do prezentera. Prezenter jest także odłączany bezpośrednio od Widoku i rozmawia z nim za pośrednictwem interfejsu. Ma to umożliwić przedrzeźnianie widoku w teście jednostkowym. Jednym z powszechnych atrybutów MVP jest to, że musi istnieć wiele dwukierunkowych wysyłek. Na przykład, gdy ktoś kliknie przycisk "Zapisz", funkcja obsługi zdarzeń deleguje do metody "Zapas" prezentera. Po zakończeniu zapisywania prezenter następnie oddzwoni do widoku poprzez jego interfejs, aby widok mógł wyświetlić, że zapis został zakończony.

MVP wydaje się być bardzo naturalnym wzorem do osiągnięcia oddzielnej prezentacji w Formularzach sieciowych. Powodem jest to, że widok jest zawsze tworzony najpierw przez środowisko wykonawcze ASP.NET. Możesz dowiedz się więcej o obu wariantach.

Dwie podstawowe odmiany

Widok pasywny: Widok jest tak głupi jak to możliwe i zawiera prawie zerową logikę. Presenter to środkowy człowiek, który rozmawia z View and the Model. Widok i model są całkowicie ekranowane. Model może podnosić zdarzenia, ale prezenter subskrybuje je, aby zaktualizować widok. W widoku pasywnym nie ma bezpośredniego powiązania danych, zamiast tego widok udostępnia właściwości ustawiające, których prezenter używa do ustawiania danych. Wszystkim stanem zarządza prezenter, a nie widok.

  • Pro: maksymalna powierzchnia testowalności; czyste oddzielenie widoku i modelu
  • Con: więcej pracy (na przykład wszystkie właściwości ustawiacza), ponieważ sam wykonujesz wszystkie powiązania danych.

Kontroler nadzorujący: Presenter obsługuje gesty użytkownika. Widok wiąże się bezpośrednio z modelem poprzez powiązanie danych. W takim przypadku zadaniem prezentera jest przekazanie modelu do widoku, aby mógł go powiązać. Presenter będzie również zawierał logikę gestów takich jak naciśnięcie przycisku, nawigacja itp.

  • Pro: dzięki wykorzystaniu powiązania danych ilość kodu zostaje zmniejszona.
  • Con: jest mniej testowalna powierzchnia (ze względu na wiązanie danych) i jest mniej enkapsulacji w widoku, ponieważ rozmawia bezpośrednio z modelem.

Kontroler widoku modelu

w MVC, kontroler jest odpowiedzialny za określenie, który widok ma być wyświetlany w odpowiedzi na dowolne działanie, w tym przy ładowaniu aplikacji. Różni się to od MVP, w którym akcje prowadzą przez View to the Presenter. W MVC każda akcja w widoku koreluje z wywołaniem kontrolera wraz z akcją. W sieci każde działanie wiąże się z wywołaniem adresu URL, po drugiej stronie którego znajduje się kontroler, który odpowiada. Po zakończeniu przetwarzania przez kontroler zwróci on poprawny widok. Sekwencja zachowuje się w ten sposób przez cały czas trwania aplikacji:

Akcja w widoku
        -> Zadzwoń do kontrolera
        -> Logika sterownika
        -> Kontroler zwraca widok.

Inną dużą różnicą dotyczącą MVC jest to, że Widok nie wiąże się bezpośrednio z Modelem. Widok po prostu renderuje i jest całkowicie bezpaństwowy. W implementacjach MVC View zwykle nie będzie mieć żadnej logiki w kodzie. Jest to sprzeczne z MVP, gdzie jest to absolutnie konieczne, ponieważ jeśli widok nie przekazuje prezentacji prezenterowi, nigdy nie zostanie wywołany.

Model prezentacji

Innym wzorem, na który można spojrzeć, jest Model prezentacji wzór. W tym modelu nie ma prezentera. Zamiast tego widok wiąże się bezpośrednio z modelem prezentacji. Model prezentacji to model stworzony specjalnie dla widoku. Oznacza to, że ten model może wyeksponować właściwości, których nigdy nie można zastosować w modelu domeny, ponieważ byłoby to naruszeniem separacji interesów. W takim przypadku model prezentacji wiąże się z modelem domeny i może subskrybować zdarzenia pochodzące z tego modelu. Widok następnie subskrybuje zdarzenia pochodzące z modelu prezentacji i odpowiednio się aktualizuje. Model prezentacji może wystawiać polecenia, których widok używa do wywoływania akcji. Zaletą tego podejścia jest to, że zasadniczo można całkowicie usunąć kod z tyłu, ponieważ PM całkowicie hermetyzuje wszystkie zachowania dla widoku. Ten wzorzec jest bardzo dobrym kandydatem do zastosowania w aplikacjach WPF i jest również nazywany Model-View-ViewModel.

Tam jest Artykuł MSDN o modelu prezentacji i sekcja w Wytyczne dotyczące aplikacji złożonych dla WPF (były Prism) o Oddzielne wzory prezentacji


1803
2017-08-05 10:21



Czy możesz wyjaśnić to zdanie? Różni się to od MVP, w którym akcje prowadzą przez View to the Presenter. W MVC każda akcja w widoku koreluje z wywołaniem kontrolera wraz z akcją. Dla mnie to brzmi jak to samo, ale jestem pewien, że opisujesz coś innego. - Panzercrisis
@ Panzercrisis Nie jestem pewien, czy to jest to, co autor miał na myśli, ale to jest to, co myślę, że próbowali powiedzieć. Podoba mi się ta odpowiedź - stackoverflow.com/a/2068/74556 w MVC metody kontrolerów opierają się na zachowaniach - innymi słowy, możesz mapować wiele widoków (ale to samo zachowanie) do pojedynczego kontrolera. W MVP prezenter jest sprzężony bliżej widoku i zwykle skutkuje odwzorowaniem, które jest bliższe jeden do jednego, tj. Działanie widoku jest odwzorowywane do odpowiadającej mu metody prezentera. Zazwyczaj nie zamapowano działań innego widoku na metodę innego prezentera (z innego widoku). - Dustin Kendall


Blogowałem o tym chwilę, cytując Znakomity post Todd Snyder na temat różnicy między tymi dwoma:

Oto kluczowe różnice między   wzory:

Wzór MVP

  • Widok jest luźniej powiązany z modelem. Prezenter jest   odpowiedzialny za związanie modelu z   widok.
  • Łatwiejszy test jednostkowy, ponieważ interakcja z widokiem jest zakończona   interfejs
  • Zwykle wyświetlaj mapę dla prezentera jeden do jednego. Złożone widoki mogą mieć   wielu prezenterów.

Wzór MVC

  • Kontroler jest oparty na zachowaniach i może być współdzielony   widoki
  • Może być odpowiedzialny za określenie, który widok wyświetlić

To najlepsze wytłumaczenie w Internecie, jakie mogłem znaleźć.


385
2017-07-06 22:18



Nie rozumiem, jak w widoku można powiązać mniej więcej z modelem, gdy w obu przypadkach cały punkt polega na ich całkowitym rozłączeniu. Nie sugeruję, że powiedziałeś coś złego - po prostu pomyliłeś się, co masz na myśli. - Bill K
@ Pst: z MVP to naprawdę 1 View = 1 Presenter. W przypadku MVC kontroler może zarządzać wieloma widokami. To wszystko, naprawdę. W modelu "zakładki" wyobraź sobie, że każda zakładka ma swój własny Prezenter, a nie ma jednego Kontrolera dla wszystkich kart. - Jon Limjap
Początkowo istnieją dwa typy kontrolerów: ten, który powiedziałeś, że jest współużytkowany w wielu widokach, oraz te, które są specyficzne dla widoków, głównie przeznaczone do dostosowania interfejsu współdzielonego kontrolera. - Acsor
@JonLimjap Co to oznacza w przypadku jednego widoku? Czy w kontekście programowania w systemie iOS ma on charakter jednoekranowy? Czy to sprawia, że ​​kontroler iOS bardziej przypomina MVP niż MVC? (Z drugiej strony możesz mieć także wiele kontrolerów iOS na ekranie) - huggie
Diagramowa ilustracja MVC autorstwa Well Todd całkowicie przeczy idei oddzielenia widoku i modelu. Jeśli spojrzysz na diagram, zobaczysz widok Aktualizacje modelu (strzałka od modelu do widoku). W którym wszechświecie jest system, w którym Model bezpośrednio wchodzi w interakcję z Widokiem, odsprzęgnięty? - Ash


Jest to nadmierne uproszczenie wielu wariantów tych wzorców projektowych, ale w ten sposób lubię myśleć o różnicach między tymi dwoma.

MVC

MVC

MVP

enter image description here


367
2017-09-12 20:47



Jest to świetny obraz schematu, pokazujący abstrakcję i całkowitą izolację dowolnego interfejsu GUI (widok rzeczy) z API prezentera. Jeden mały punkt: Mistrzowski prezenter może być używany tam, gdzie jest tylko jeden prezenter, a nie jeden na widok, ale twój diagram jest najczystszy. IMO, największą różnicą między MVC / MVP jest to, że MVP stara się utrzymać widok całkowicie pozbawiony niczego poza wyświetlaniem bieżącego "stanu widoku" (dane widoku), jednocześnie nie dopuszczając do widoku żadnej wiedzy o obiektach Modelu. Zatem interfejsy, które muszą tam być, aby wstrzyknąć ten stan.
Dobre zdjęcie. Często używam MVP, więc chciałbym przedstawić jeden punkt. Z mojego doświadczenia wynika, że ​​prelegenci muszą często rozmawiać ze sobą. To samo dotyczy modeli (lub obiektów biznesowych). Z powodu tych dodatkowych "niebieskich linii" komunikacji, które byłyby w twoim obrazie MVP, relacje prezenter-model mogą stać się dość splątane. Dlatego też staram się utrzymywać relację prezenter-model jeden do jednego a jeden do wielu. Tak, wymaga pewnych dodatkowych metod delegowania na Model, ale zmniejsza wiele bólów głowy, jeśli API Modelu zmienia się lub wymaga refaktoryzacji. - splungebob
Przykład MVC jest błędny; istnieje ścisła relacja 1: 1 między widokami a kontrolerami. Z definicji sterownik interpretuje wprowadzane gesty człowieka, aby tworzyć zdarzenia dla modelu i widoku dla pojedynczej kontroli. Mówiąc prościej, MVC było przeznaczone wyłącznie do użytku z pojedynczymi widgetami. Jeden widget, jeden widok, jedna kontrolka. - Samuel A. Falvo II
@ SamuelA.FalvoII nie zawsze istnieje 1: wiele między kontrolerami i widokami w ASP.NET MVC: stackoverflow.com/questions/1673301/... - StuperUser
@StuperUser - Nie jestem pewien, co myślałem, kiedy to napisałem. Masz rację, i patrząc wstecz na to, co napisałem, muszę się zastanowić, czy mam na myśli jakiś inny kontekst, którego nie udało mi się wyartykułować. Dziękuję za poprawienie mnie. - Samuel A. Falvo II


Oto ilustracje reprezentujące przepływ komunikacji

enter image description here 

enter image description here


210
2017-08-25 21:22



Mam pytanie dotyczące diagramu MVC. Nie dostaję części, gdzie widok wychodzi do pobierania danych. Myślę, że kontroler przesyła do widoku z potrzebnymi danymi. - Brian Rizo
Jeśli użytkownik kliknie przycisk, w jaki sposób nie wchodzi on w interakcję z widokiem? Czuję się jak w MVC, użytkownik współdziała z widokiem bardziej niż kontroler - Jonathan
Wiem, że to stara odpowiedź, ale czy ktoś może odpowiedzieć na @JonathanLeaders? Pochodzę z tła WinForms, chyba że zrobiłeś bardzo unikatowe kodowanie, kiedy klikniesz UI / Widok otrzymasz wiedzę o tym kliknięciu, zanim cokolwiek innego. Przynajmniej, o ile wiem? - Rob P.
@RobP. Myślę, że tego rodzaju wykresy zawsze wydają się zbyt skomplikowane lub zbyt proste. Imo przepływ wykresu MVP odnosi się również do aplikacji MVC. Mogą występować różnice w zależności od funkcji językowych (powiązanie danych / obserwator), ale ostatecznie chodzi o oddzielenie widoku od danych / logiki aplikacji. - Luca Fülbier
@ JonathanLeaders Ludzie mają naprawdę o różnych rzeczach, kiedy mówią "MVC". Osoba, która stworzyła ten wykres, miała prawdopodobnie na myśli klasyczną sieć MVC, w której "dane wejściowe użytkownika" to żądania HTTP, a "widok zwrócony użytkownikowi" to wyrenderowana strona HTML. Tak więc jakakolwiek interakcja między użytkownikiem a widokiem jest "nieistniejąca" z punktu widzenia autora klasycznej aplikacji internetowej MVC. - cubuspl42


MVP to nie koniecznie scenariusz, w którym Widok jest odpowiedzialny (patrz na przykład MVP Taligent).
Uważam, że to niefortunne, że ludzie wciąż głoszą to jako wzorzec ("View in charge"), w odróżnieniu od anty-wzorców, ponieważ jest to sprzeczne z "It's just a view" (Pragmatic Programmer). "To tylko widok" stwierdza, że ​​ostateczny widok przedstawiony użytkownikowi jest drugorzędnym problemem aplikacji. Wzorzec MVP Microsoftu sprawia, że ​​ponowne korzystanie z Widoku jest znacznie trudniejsze i wygodnie usprawiedliwia projektanta Microsoftu od zachęcania do złych praktyk.

Aby być całkowicie szczerym, myślę, że podstawowe obawy MVC są prawdziwe dla każdej implementacji MVP, a różnice są prawie całkowicie semantyczne. Tak długo, jak obserwujesz rozdzielenie obaw pomiędzy widokiem (wyświetlającym dane), kontrolerem (który inicjalizuje i kontroluje interakcję użytkownika) i modelem (dane i / lub usługi)), wtedy osiągasz korzyści z MVC . Jeśli czerpiesz korzyści, to kto naprawdę dba o to, czy Twój wzór to MVC, MVP czy kontroler nadzoru? Jedyny real wzór pozostaje jak MVC, reszta to po prostu odmienne smaki tego.

Rozważać to bardzo ekscytujący artykuł, który wyczerpująco wylicza wiele tych różnych implementacji. Możesz zauważyć, że wszyscy robią to samo, ale nieco inaczej.

Osobiście uważam, że MVP został niedawno ponownie wprowadzony jako chwytliwy termin, aby zredukować argumenty pomiędzy semantycznymi bigotami, którzy twierdzą, że coś jest naprawdę MVC lub nie, lub usprawiedliwić narzędzia Microsoft Rapid Application Development. Żadna z tych przyczyn w moich książkach nie uzasadnia jej istnienia jako osobnego wzorca projektowego.


149
2017-08-06 22:51



Czytałem kilka odpowiedzi i blogów na temat różnic między MVC / MVP / MVVM / etc ". W efekcie, gdy jesteś w biznesie, wszystko jest takie samo. Nie ma znaczenia, czy masz interfejs, czy nie i czy używasz setera (lub jakiejkolwiek innej funkcji językowej). Wydaje się, że różnica między tymi wzorcami zrodziła się z różnicy różnych implementacji ram, a nie z kwestii koncepcji. - Michael
Nie nazwałbym MVP an anty-wzór, jak później w poście "... reszta [w tym MVP] są po prostu różnymi smakami [MVC] ..", co oznaczałoby, że gdyby MVP było anty-wzorem, tak samo było z MVC ... to jest po prostu smak dla inne podejście ramowe. (Teraz niektórzy konkretny Implementacje MVP mogą być mniej lub bardziej pożądane niż niektóre konkretny Implementacje MVC do różnych zadań ...)
@Quibblsome: "Osobiście uważam, że MVP zostało ostatnio ponownie wprowadzone jako chwytliwe określenie, aby zredukować argumenty pomiędzy semantycznymi bigotami, którzy argumentują, czy coś jest naprawdę MVC, czy nie [...] Żaden z tych powodów w moich książkach nie usprawiedliwia jego istnienia jako oddzielny wzór. ". Różni się na tyle, że jest wyraźny. W MVP widok może być wszystkim, co spełnia predefiniowany interfejs (widok w MVP jest samodzielnym komponentem). W MVC kontroler jest tworzony dla określonego widoku (jeśli aranżacje relacji mogą sprawić, że ktoś poczuje, że jest wart innego terminu). - Hibou57
@ Hibou57, nic nie stoi na przeszkodzie, aby MVC odwoływał się do widoku jako interfejsu lub tworzenia ogólnego kontrolera dla kilku różnych widoków. - Quibblesome
@quibblesome faktycznie, jest. Kontrolery są z definicji ściśle związane z ich odpowiednimi widokami, ponieważ ich zadaniem jest interpretowanie ludzkich gestów (naciśnięcia klawiszy, aktualizacje myszy itp.) W zdarzenia dla indywidualne kontrole w oknie. Właśnie dlatego masz ścisły jeden kontroler, jedną relację widoku. Kontrolery były nigdy przeznaczone do stosowania w całym formularzu. W przypadku całej formy powstał Model Aplikacji (znany również jako Model Prezentacji), który lepiej odpowiada temu celowi. Ponieważ interfejsy graficzne innych niż Smalltalk nie opierają się na MVC w celu implementacji kontrolek, MVC ma stosunkowo niewielki sens w praktyce. - Samuel A. Falvo II


MVP: widok jest odpowiedzialny.

Widok, w większości przypadków, tworzy swojego prezentera. Prezenter będzie wchodził w interakcje z modelem i manipuluje widokiem za pośrednictwem interfejsu. Widok czasami będzie wchodził w interakcję z prezenterem, zwykle poprzez jakiś interfejs. Sprowadza się to do wdrożenia; Czy chcesz, aby widok wywoływał metody na prezentera, czy chcesz, aby widok miał prezentowane przez prezentera? Sprowadza się do tego: widok wie o prezencie. Widok deleguje do prezentera.

MVC: kontroler jest odpowiedzialny.

Sterownik jest tworzony lub uruchamiany na podstawie jakiegoś zdarzenia / żądania. Kontroler następnie tworzy odpowiedni widok i współdziała z modelem, aby dalej skonfigurować widok. Sprowadza się do: kontroler tworzy i zarządza widokiem; widok jest niewolnikiem kontrolera. Widok nie zna kontrolera.


90
2017-12-20 02:10



"Widok nie wie o sterowniku". Myślę, że masz na myśli to, że widok nie ma bezpośredniego kontaktu z modelem? - Lotus Notes
widok nigdy nie powinien wiedzieć o modelu w eiether. - Brian Leahy
@Brian: "Widok w większości przypadków tworzy jego Prezenter.". Zasadniczo widziałem coś przeciwnego, gdy prezenter uruchomił zarówno model, jak i widok. Widok może również uruchomić prezentera, ale ten punkt nie jest tak naprawdę najbardziej charakterystyczny. To, co najważniejsze, dzieje się później podczas życia. - Hibou57
Możesz edytować swoją odpowiedź, aby wyjaśnić dalej: skoro widok nie wie o sterowniku, w jaki sposób działania użytkownika są wykonywane na elementach "wizualnych", które użytkownik widzi na ekranie (tj. Widoku), przekazanych kontrolerowi ... - Ash


enter image description here

MVC (kontroler widoku modelu)

Dane wejściowe są kierowane najpierw do kontrolera, a nie do widoku. Dane te mogą pochodzić od interakcji użytkownika ze stroną, ale może to być po prostu wpisanie konkretnego adresu URL w przeglądarce. W obu przypadkach jest to kontroler połączony z nim, aby uruchomić niektóre funkcje. Istnieje relacja wiele do jednego między kontrolerem a widokiem. Wynika to z faktu, że pojedynczy kontroler może wybrać różne widoki, które mają być renderowane na podstawie wykonywanej operacji. Zwróć uwagę na strzałkę w jedną stronę od kontrolera do widoku. Dzieje się tak dlatego, że widok nie ma żadnej wiedzy na temat kontrolera ani nie ma do niego odniesienia. Kontroler przesyła z powrotem model, więc istnieje wiedza między widokiem a oczekiwanym modelem, który jest przekazywany do niego, ale nie kontroler obsługujący go.

MVP (Presenter widoku modelu)

Dane wejściowe zaczynają się od widoku, a nie od prezentera. Istnieje mapowanie jeden-do-jednego między widokiem a powiązanym prezenterem. Widok zawiera odniesienie do prezentera. Prezenter reaguje również na zdarzenia wywoływane z Widoku, dzięki czemu jest świadomy Widoku, z którym jest skojarzony. Presenter aktualizuje widok na podstawie żądanych działań, które wykonuje na modelu, ale widok nie jest świadomy modelu.

Więcej Odniesienie


62
2017-08-05 10:22



Ale w MVP wzór, kiedy aplikacja ładuje się po raz pierwszy, czy prezenter nie jest odpowiedzialny za załadowanie pierwszego widoku? Na przykład, gdy ładujemy aplikację facebookową, czy prezenter nie jest odpowiedzialny za załadowanie strony logowania? - viper
Łącze od modelu do widoku w MVC? Możesz edytować swoją odpowiedź, aby wyjaśnić, w jaki sposób czyni to system "niezwiązanym" z tym łączem. Wskazówka: może ci się to wydawać trudne. Poza tym, jeśli uważasz, że czytelnik z radością nie zaakceptuje, że cały czas źle się spisują, możesz zastanowić się, dlaczego akcje przechodzą najpierw przez kontroler w MVC, mimo że użytkownik wchodzi w interakcję z "wizualnymi" elementami na ekranie (tj. View), a nie jakiejś abstrakcyjnej warstwy, która znajduje się za przetwarzaniem. - Ash
To powinna być zaakceptowana odpowiedź. jasne i zwięzłe - Nelson Ramirez