Jaka jest różnica między MVC i MVVM? [Zamknięte]


1312

Czy istnieje różnica między standardowym wzorcem „Model View Controller” a wzorcem Microsoft Model / View / ViewModel?


54
Zauważ, że chociaż MVVM został wymyślony przez Microsoft, wielu deweloperów i projektów innych niż Microsoft zaczęło stosować ten wzorzec. Ten komentarz przyniósł ci dział nienawiści na przekór stwardnieniu rozsianemu.
BoltClock

1
Pracując z MVVM przez długi czas, mój pierwszy pędzel z MVC był frustrujący, dopóki nie dowiedziałem się, że mogę przekazywać ViewModels w tę iz powrotem do przeglądarki przy użyciu technik wiązania znalezionych w MVVM. Ale jak powiedział wcześniej Joel, jedynym sposobem na przywrócenie stanu z przeglądarki jest opublikowanie zmian w formularzu (który używa par nazwa / wartość). Jeśli nie rozumiesz dobrze tego punktu. Będziesz miał trudności w MVC. Wystarczy spojrzeć na kontroler jako wtryskiwacz zależności dla widoku i gotowe.
John Peters

2
Takie popularne pytanie na wysokim poziomie [wzorce projektowe]. Chciałbym zasugerować użycie diagramów na odpowiedziach.
Ricardo


1
W przeciwieństwie do metody MVC ViewModel nie jest kontrolerem. Zamiast tego działa jak spoiwo, które wiąże dane między widokiem a modelem. Podczas gdy format MVC został specjalnie zaprojektowany, aby stworzyć rozdzielenie obaw między modelem a widokiem, format MVVM z wiązaniem danych został zaprojektowany specjalnie, aby umożliwić widokowi i modelowi komunikację bezpośrednio ze sobą. hackernoon.com/...
BlueRay

Odpowiedzi:


684

MVC / MVVM nie jest / ani wyborem.

Te dwa wzorce pojawiają się na różne sposoby, zarówno w rozwoju ASP.Net, jak i Silverlight / WPF.

W przypadku ASP.Net MVVM służy do dwukierunkowego wiązania danych w widokach. Zazwyczaj jest to implementacja po stronie klienta (np. Za pomocą Knockout.js). Z drugiej strony MVC jest sposobem na rozdzielenie problemów po stronie serwera .

W przypadku Silverlight i WPF wzorzec MVVM jest bardziej obejmujący i może wydawać się zastępować MVC (lub inne wzorce organizowania oprogramowania w oddzielne obowiązki). Jednym z założeń, które często wyszedł z tego wzoru, było to, że ViewModelpo prostu wymienić regulator w MVC(jakby można po prostu zastąpić VMna Cw akronimem i wszystko zostanie wybaczone) ...

ViewModel ma nie koniecznie zastąpić potrzebę oddzielnych kontrolerów.

Problem polega na tym, że aby być niezależnie testowalnym *, a szczególnie wielokrotnego użytku w razie potrzeby, model widoku nie ma pojęcia, jaki widok go wyświetla, ale co ważniejsze, nie ma pojęcia, skąd pochodzą jego dane .

* Uwaga: w praktyce Kontrolery usuwają większość logiki z ViewModel, która wymaga testów jednostkowych. Maszyna wirtualna staje się wówczas głupim kontenerem, który wymaga niewiele testów, o ile w ogóle je ma. To dobrze, ponieważ VM jest tylko pomostem między projektantem a programistą, dlatego należy zachować prostotę.

Nawet w MVVM kontrolery zwykle zawierają całą logikę przetwarzania i decydują, jakie dane wyświetlić, w których widokach, używając modeli widoków.

Z tego, co widzieliśmy do tej pory, główną zaletą wzorca ViewModel jest usunięcie kodu z kodu XAML z tyłu, aby edycja XAML była bardziej niezależnym zadaniem . Nadal tworzymy kontrolery, w razie potrzeby, w celu kontrolowania (bez zamierzonej gry słów) ogólnej logiki naszych aplikacji.

Podstawowe przestrzegane przez nas wytyczne MVCVM to:

  • Widoki wyświetlają określony kształt danych . Nie mają pojęcia, skąd pochodzą dane.
  • ViewModels przechowują określony kształt danych i poleceń , nie wiedzą, skąd dane lub kod pochodzą ani jak są wyświetlane.
  • Modele przechowują rzeczywiste dane (różne konteksty, przechowywanie lub inne metody)
  • Kontrolery nasłuchują i publikują zdarzenia. Kontrolery zapewniają logikę, która kontroluje, jakie dane są widziane i gdzie. Kontrolery dostarczają kod polecenia do ViewModel, dzięki czemu ViewModel jest rzeczywiście wielokrotnego użytku.

Zauważyliśmy również, że struktura kodu genów rzeźby implementuje MVVM i wzorzec podobny do Prism ORAZ, a także szeroko wykorzystuje kontrolery do oddzielenia całej logiki przypadków użycia.

Nie zakładaj, że kontrolery stają się nieaktualne przez modele View.

Założyłem blog na ten temat, do którego dodam, kiedy i kiedy będę mógł . Występują problemy z łączeniem MVCVM ze zwykłymi systemami nawigacji, ponieważ większość systemów nawigacji korzysta tylko z widoków i maszyn wirtualnych, ale przejdę do tego w późniejszych artykułach.

Dodatkową zaletą korzystania z modelu MVCVM jest to, że tylko obiekty kontrolera muszą istnieć w pamięci przez cały okres użytkowania aplikacji, a kontrolery zawierają głównie kod i niewiele danych o stanie (tj. Niewielki narzut pamięci). To sprawia, że ​​aplikacje zużywają dużo mniej pamięci niż rozwiązania, w których muszą być zachowane modele widoków i jest to idealne rozwiązanie dla niektórych rodzajów programowania urządzeń mobilnych (np. Windows Mobile przy użyciu Silverlight / Prism / MEF). Zależy to oczywiście od rodzaju aplikacji, ponieważ może być konieczne zachowanie sporadycznie buforowanych maszyn wirtualnych w celu zapewnienia czasu reakcji.

Uwaga: ten post był edytowany wiele razy i nie był specjalnie ukierunkowany na wąskie zadane pytanie, więc zaktualizowałem pierwszą część, aby teraz również to obejmować. Duża część dyskusji, w komentarzach poniżej, dotyczy tylko ASP.Net, a nie szerszego obrazu. Ten post miał na celu szersze zastosowanie MVVM w Silverlight, WPF i ASP.Net i starał się zniechęcić ludzi do zamiany kontrolerów na ViewModels.


8
@Tomasz Zieliński: To prawda, ale „gdzie są używane” nie było pytaniem (ani sednem mojej odpowiedzi). Chodzi mi o to, że kontrolery są nadal przydatne w MVVM.
Gone Coding

58
Zgadzam się. Mój komentarz był spowodowany nagłym oświeceniem, a nie dlatego, że się z tobą nie zgadzałem.
Tomasz Zieliński

Użyliśmy również kontrolerów do kontrolowania „przepływu” widoków w interfejsie użytkownika podobnym do kreatora.
riezebosch

3
@Justin: Widzę, że moje brzmienie tego zdania jest trochę niejednoznaczne. Chodzi mi o to, że testy jednostkowe dla wszystkich komponentów są łatwiej obsługiwane, a nie tylko ulepszanie testowania ViewModels (które, jak zauważyłeś, nie robią tak wiele w MVCVM ... to jest to, czego chcesz). Prawdziwą zaletą kontrolerów jest to, że w rzeczywistości usuwasz większość wymagań dotyczących testowania z ViewModel (gdzie ludzie popychają logikę kontrolera) i umieszczasz go tam, gdzie można go przetestować (głównie kontrolery i modele). Komentarz do ponownego użycia jest specyficzny dla maszyn wirtualnych w tym zdaniu. Zredagowałem to.
Gone Coding

7
@TomaszZielinski M (MVVM) C
Mohamed Emad,

273

Myślę, że najłatwiejszym sposobem na zrozumienie, co oznaczają te akronimy, jest chwilowe zapomnienie o nich. Zamiast tego pomyśl o oprogramowaniu, z którego pochodzą, o każdym z nich. To naprawdę sprowadza się do różnicy między wczesną siecią a komputerem.

Wraz ze wzrostem złożoności w połowie 2000 r. Wzorzec projektowania oprogramowania MVC - po raz pierwszy opisany w latach 70. XX wieku - zaczął być stosowany do aplikacji internetowych. Pomyśl między bazą danych, stronami HTML i kodem. Udoskonalmy to trochę, aby dotrzeć do MVC: dla »bazy danych« załóżmy bazę danych plus kod interfejsu. Dla »stron HTML« załóżmy szablony HTML plus kod przetwarzania szablonów. Dla »kodu pomiędzy« załóżmy, że użytkownik mapuje kod kliknięć użytkownika na działania, prawdopodobnie wpływając na bazę danych, zdecydowanie powodując wyświetlenie innego widoku. To wszystko, przynajmniej na potrzeby tego porównania.

Zachowajmy jedną cechę tych rzeczy, nie tak jak dzisiaj, ale tak jak istniała dziesięć lat temu, kiedy JavaScript był nędzną, nikczemną irytacją, której prawdziwi programiści dobrze unikali: strona HTML jest zasadniczo głupia i pasywna . Przeglądarka jest cienkim klientem lub, jeśli wolisz, słabym klientem. W przeglądarce nie ma inteligencji. Reguła przeładowania całej strony. „Widok” jest generowany za każdym razem od nowa.

Pamiętajmy, że ten internetowy sposób, mimo że jest wściekły, był okropnie zacofany w porównaniu do pulpitu. Aplikacje komputerowe to grubi klienci lub bogaci klienci, jeśli wolisz. (Nawet taki program jak Microsoft Word można uznać za pewnego rodzaju klienta, klienta dokumentów.) Są to klienci pełni inteligencji, wiedzy o swoich danych. Są stanowe. Przechowują w pamięci dane, które przetwarzają. Żadnych takich badziewi jak pełne przeładowanie strony.

I ten bogaty sposób pulpitu prawdopodobnie pochodzi od drugiego akronimu, MVVM. Nie daj się zwieść literom, pominięciu C. Kontrolery wciąż tam są. Muszą być. Nic nie zostanie usunięte. Dodajemy tylko jedną rzecz: stan, dane buforowane na kliencie (a wraz z nim inteligencja do obsługi tych danych). Te dane, zasadniczo pamięć podręczna klienta, są teraz nazywane »ViewModel«. To pozwala na bogatą interaktywność. I to wszystko.

  • MVC = model, kontroler, widok = zasadniczo komunikacja jednokierunkowa = słaba interaktywność
  • MVVM = model, kontroler, pamięć podręczna, widok = dwustronna komunikacja = bogata interaktywność

Widzimy, że dzięki Flash, Silverlight i - co najważniejsze - JavaScript, Internet objął MVVM. Przeglądarek nie można już legalnie nazywać cienkimi klientami. Spójrz na ich programowalność. Spójrz na ich zużycie pamięci. Spójrz na całą interaktywność Javascript na nowoczesnych stronach internetowych.

Osobiście uważam tę teorię i akronim za łatwiejszy do zrozumienia, patrząc na to, do czego się odnosi w konkretnej rzeczywistości. Pojęcia abstrakcyjne są przydatne, zwłaszcza gdy są prezentowane na konkretnej materii, więc zrozumienie może zatoczyć koło.

 


47
MVC nie pochodzi z sieci. Trygve Reenskaug wprowadził MVC do Smalltalk-76 w 1970 roku.
Arialdo Martini

11
Nawet jeśli zmieniono go na „MVC spopularyzowano poprzez projektowanie aplikacji internetowych”. Twierdziłbym, że jest to spekulacja bez odpowiedniego cytowania.
Dan Bechard

4
Arialdo: Dzięki, nie wiedziałem o Smalltalk-76. (Grałem wtedy z innymi zabawkami.) Na bok żarty, ciekawe, ile lat mają niektóre z tych koncepcji. - @Dan, co napisałem to: „[MVC] mógł być tam przed [siecią], ale sieć jest sposobem, w jaki została spopularyzowana wśród masowych programistów”. Nadal uważam, że to prawda. Nie mam na to żadnego wzmianki, ale nie sądzę, żebym go potrzebował, ponieważ popularyzacja mas MVC jest częścią mojego osobistego doświadczenia, gdy zaczynałem jako programista na początku ostatniej dekady. Apache Struts było wtedy modne, z dużą ilością fasoli dla MVC.
Lumi

5
MVC nie jest „zasadniczo jednokierunkową komunikacją”, ponieważ przeglądarki cały czas wysyłają komunikaty „Gets and Post”. Pobiera i wysyła wiadomości może zmieniać wartości pól znalezione w ciągu zapytania. Daje to przeglądarkom szerokie możliwości przesyłania informacji z powrotem do kontrolera. MVC został zbudowany na bazie protokołu HTTP 1.0, który zawsze miał na uwadze dwukierunkową komunikację.
John Peters

13
Dzięki Lumi. To było dla mnie o wiele bardziej sensowne niż inne odpowiedzi. Czy to jest poprawne? Nie mam pojęcia. Ale z mojej perspektywy było to co najmniej spójne.
gcdev

175

MVVM Model-View ViewModel jest podobny do MVC, Model-View Controller

Kontroler zastąpiono ViewModel . ViewModel znajduje się poniżej warstwy interfejsu użytkownika. ViewModel udostępnia obiekty danych i poleceń, których potrzebuje widok. Możesz myśleć o tym jak o obiekcie kontenerowym, z którego widok pobiera dane i akcje. ViewModel pobiera dane z modelu.

Russel East prowadzi blog omawiający bardziej szczegółowo Dlaczego MVVM różni się od MVC


81
Zdanie „Kontroler jest zastąpiony modelem widoku” jest niepoprawne. W MVVM rolą kontrolera jest wiązanie danych (lub wiązanie umowne, jeśli go używasz).
DaniCE

9
MVVM ma sens tylko wtedy, gdy używa się dwukierunkowego powiązania danych WPF. W przeciwnym razie wystarczy MVC / MVP itp.
Jeff

265
@DaniCE: Josh Smith:If you put ten software architects into a room and have them discuss what the Model-View-Controller pattern is, you will end up with twelve different opinions. …
sll

7
@OmShankar 11 miejsce nie jest od ciebie. Jest 10 osób ogółem i 12 opinii ogółem. To powiedzenie ma sugerować, że definicje tych wzorów są tak otwarte na interpretację, że co najmniej dwie osoby będą na tyle zdezorientowane, aby mieć więcej niż jedną opinię.
Dan Bechard

7
@DaniCE Cóż, to jest właśnie punkt wiązania danych WPF, a Microsoft wynalazł MVVM, w którym można całkowicie ominąć kontroler (twierdząc, że zdanie „Kontroler jest zastępowany modelem widoku” jest niepoprawne tylko dlatego, że istnieje kontroler za kulisami, jest w zasadzie jak twierdzenie, że „wyższy poziom języka zamienia użycie tajemniczego kodu maszynowego na bardziej czytelny”, aby był niepoprawny, ponieważ za kulisami nadal używany jest język maszynowy ...)
yoel halb

91

Po pierwsze, MVVM jest postępem wzoru MVC, który używa XAML do obsługi wyświetlania. W tym artykule opisano niektóre aspekty tych dwóch aspektów.

Głównym założeniem architektury Model / View / ViewModel wydaje się być to, że na wierzchu danych („Model”) znajduje się kolejna warstwa komponentów niewizualnych („ViewModel”), które dokładniej odwzorowują pojęcia danych do koncepcji widoku danych („Widok”). Jest to ViewModel, z którym łączy się widok, a nie bezpośrednio model.


20
Myślę, że akapit, który zacytowałeś, ładnie to podsumowuje IMHO. Aspekt ViewModel polega na tym, że jest to spłaszczona / zmieniona wersja modelu dla widoku. Wiele innych wzorów MV * wiąże się z rzeczywistym modelem.
Daniel Auger,

1
„Wiele innych wzorów MV * ponownie wiąże prawdziwy model”? Naprawdę? Myślałem, że widok powinien zawsze wiązać się z kontrolerem w MVC, bez względu na wszystko.
PlagueHammer

9
Nocturne: W klasycznym MVC View nie ma wiele wspólnego z kontrolerem, wiąże się głównie z Modelem. Pomyśl o tym jak o robocie - Model reprezentuje pozycję stawów robota, Widok to monitor LCD, na którym widzisz robota, Kontroler to np. Klawiatura. W takiej konfiguracji Widok zależy od Modelu, tzn. Przestrzenna pozycja robota, którą można zobaczyć na monitorze, jest bezpośrednią reprezentacją Modelu.
Tomasz Zieliński

@Nocturne Wydawało się, że Daniel powiedział, że chociaż oficjalnie wszystkie MV * powinny używać osobnej maszyny wirtualnej, wielu programistów po prostu ją ignoruje i przekazuje rzeczywisty model, aw rzeczywistości nic w specyfikacjach na przykład MVC nie zezwala na to, jednak w MVVM jeden maszyna wirtualna musi być odpowiedzialna za przejście między modelem a widokiem
yoel halb

Powiedziałbym tak: model jest ściśle związany ze schematem DB. Po uruchomieniu zapytania może rzutować dane na silne typy w warstwie modelu. Viewmodel to kolekcje rzeczy, w tym obiektów modelowych, ale może utrzymywać stan widoku w odniesieniu do danych. Kontroler jest po prostu policjantem ruchu między modelem widoku a widokiem i oczywiście widok dotyczy tylko stanów widoku.
John Peters

52

Microsoft podał tutaj wyjaśnienie Wzorca MVVM w środowisku Windows .

Oto kluczowa sekcja:

We wzorcu projektowym Model-View-ViewModel aplikacja składa się z trzech ogólnych komponentów. wprowadź opis zdjęcia tutaj

  • Model : reprezentuje model danych używany przez aplikację. Na przykład w aplikacji do udostępniania zdjęć warstwa ta może reprezentować zestaw zdjęć dostępnych na urządzeniu oraz interfejs API używany do odczytu i zapisu w bibliotece obrazów.

  • Widok : aplikacja zazwyczaj składa się z wielu stron interfejsu użytkownika. Każda strona pokazana użytkownikowi jest widokiem w terminologii MVVM. Widok jest kodem XAML używanym do definiowania i stylizowania tego, co widzi użytkownik. Dane z modelu są wyświetlane użytkownikowi, a zadaniem ViewModel jest karmienie interfejsu użytkownika tymi danymi w oparciu o bieżący stan aplikacji. Na przykład w aplikacji do udostępniania zdjęć widokami będzie interfejs użytkownika, który pokazuje użytkownikowi listę albumów na urządzeniu, zdjęcia w albumie, a być może inny, który pokazuje użytkownikowi określone zdjęcie.

  • ViewModel : ViewModel łączy model danych lub po prostu model z interfejsem użytkownika lub widokami aplikacji. Zawiera logikę, za pomocą której można zarządzać danymi z modelu, i udostępnia dane jako zestaw właściwości, z którymi interfejs XAML lub widoki mogą się wiązać. Na przykład w aplikacji do udostępniania zdjęć ViewModel udostępnia listę albumów, a dla każdego albumu wyświetla listę zdjęć. Interfejs użytkownika jest niezależny od tego, skąd pochodzą zdjęcia i jak są one pobierane. Po prostu wie o zestawie zdjęć odsłoniętych przez ViewModel i pokazuje je użytkownikowi.


7
Zwróć uwagę, że chociaż wspomniany artykuł dotyczy programowania przy użyciu Microsoft Stack - w szczególności Windows Phone - i XAML, nie musi tak być.
Richard Nalezynski

Ta odpowiedź uwypukla problem z nazwą „MVVM” - powinna to być „VVMM” lub „MVMV” - MV-VM ma całkowicie niewłaściwe relacje!
Etherman,

45

Pomyślałem, że jedną z głównych różnic jest to, że w MVC twoje V odczytuje bezpośrednio M i przechodzi przez C, aby manipulować danymi, podczas gdy w MVVM, twoja maszyna wirtualna działa jako proxy M, a także zapewnia ci dostępną funkcjonalność V.

Jeśli nie jestem pełen śmieci, jestem zaskoczony, że nikt nie stworzył hybrydy, w której maszyna wirtualna jest jedynie proxy M, a C zapewnia całą funkcjonalność.


1
+1. Myślę, że termin jest poprawny. ale czy tworzenie hybryd M-MProxy-VC nie jest zbyt dużym rozdziałem? myślę, że wystarczyłoby MVC, podczas gdy M to model z pełnym wsparciem Binding. ;)
ktutnik

2
+1. Jak skomentowałem powyżej, myślę, że MVC służy do projektowania całej aplikacji (internetowej), podczas gdy MVVM jest używany w komponencie View MVC.
Tomasz Zieliński

23
@ktutnik: Model zwykle siedzi na serwerze, podczas gdy ViewModel mieszka na kliencie. Nie ma więc możliwości bezpośredniego powiązania HTML z modelem po stronie serwera. Dlatego potrzebujemy ModelView, który działa jako lokalny, niezapisany zestaw roboczy danych wyodrębniony z modelu przy użyciu np. AJAX / JSON.
Tomasz Zieliński

1
Widok rzeczywiście „odczytuje” dane modelu, ponieważ zostały już tam umieszczone przez kontroler. Lubię nazywać to „wprowadzaniem danych” przez kontroler, ponieważ tak naprawdę to on kontroluje. Cały mój widok robi w renderowaniu i odpalaniu zdarzeń w moim umyśle.
John Peters

3
Przepraszam, ale nie zgadzam się z interpretacją MVVM. ViewModel nie ma pojęcia o widoku ani o tym, jak będzie on wyglądał ani jak zareaguje, a model również nie ma pojęcia o ViewModel. W rzeczywistości widok nie powinien nawet wiedzieć o modelu, a tylko ViewModel. Model powinien reprezentować dane i stan aplikacji, ViewModel powinien tłumaczyć stan na dane obsługujące interfejs użytkownika (zalecam w tym momencie wszystkie operacje podstawowe), a widok powinien reagować na tłumaczenie ViewModels. Dane często będą takie same, ale nadal powinny być opakowane i ponownie dostarczone za pośrednictwem ViewModel i nie istnieją żadne kontrolery.
Michael Puckett II,

24

MVC jest środowiskiem kontrolowanym, a MVVM jest środowiskiem reaktywnym.

W kontrolowanym środowisku powinieneś mieć mniej kodu i wspólne źródło logiki; które powinny zawsze znajdować się w kontrolerze. Jednak; w świecie internetowym MVC łatwo dzieli się na logikę tworzenia widoków i logikę dynamiczną. Kreacja żyje na serwerze, a dynamiczna na kliencie. Widać to bardzo często w przypadku ASP.NET MVC w połączeniu z AngularJS, podczas gdy serwer utworzy widok i przekaże model i wyśle ​​go do klienta. Klient będzie wtedy wchodził w interakcję z widokiem, w którym to przypadku AngularJS wkracza jako lokalny kontroler. Po przesłaniu Model lub nowy Model jest przekazywany z powrotem do kontrolera serwera i obsługiwany. (Tak więc cykl trwa i istnieje wiele innych tłumaczeń tej obsługi podczas pracy z gniazdami, AJAX itp., Ale w całej architekturze jest identyczny.)

MVVM to środowisko reaktywne, co oznacza, że ​​zwykle piszesz kod (np. Wyzwalacze), który aktywuje się na podstawie określonego zdarzenia. W XAML, gdzie rozwija się MVVM, wszystko to można łatwo zrobić za pomocą wbudowanego szkieletu wiązania danych, ALE, jak wspomniano, będzie działać na dowolnym systemie w dowolnym widoku z dowolnym językiem programowania. To nie jest specyficzne dla SM. ViewModel odpala (zwykle zdarzenie zmieniające właściwość), a View reaguje na to w oparciu o wszelkie utworzone przez Ciebie wyzwalacze. Może to stać się techniczne, ale sedno jest takie, że widok jest bezstanowy i bez logiki. Po prostu zmienia stan na podstawie wartości. Ponadto ViewModels są bezstanowe z bardzo małą logiką, a Modele są stanem o zasadniczo zerowej logice, ponieważ powinny jedynie utrzymywać stan. Opisuję to jako stan aplikacji (Model), translator stanu (ViewModel), a następnie stan wizualny / interakcja (Widok).

W aplikacji stacjonarnej lub klienckiej MVC powinieneś mieć Model, a Model powinien być używany przez Kontroler. W zależności od modelu kontroler zmodyfikuje widok. Widoki są zwykle powiązane z kontrolerami z interfejsami, dzięki czemu kontroler może pracować z różnymi widokami. W ASP.NET logika MVC jest nieco cofnięta na serwerze, ponieważ kontroler zarządza modelami i przekazuje modele do wybranego widoku. Widok jest następnie wypełniany danymi opartymi na modelu i ma własną logikę (zwykle inny zestaw MVC, taki jak zrobiony z AngularJS). Ludzie będą się kłócić i mylą to z aplikacją MVC i spróbują zrobić oba, w których utrzymanie projektu ostatecznie stanie się katastrofą. ZAWSZE umieszczaj logikę i sterowanie w jednym miejscu podczas korzystania z MVC. NIE zapisuj logiki View w kodzie za View (lub w View poprzez JS dla sieci), aby pomieścić dane sterownika lub modelu. Pozwól, aby kontroler zmienił widok. JEDYNA logika, która powinna istnieć w Widoku, to wszystko, czego potrzeba do utworzenia i uruchomienia za pomocą interfejsu, którego używa. Przykładem tego jest podanie nazwy użytkownika i hasła. Niezależnie od tego, czy jest to komputer stacjonarny czy strona internetowa (na kliencie), kontroler powinien obsłużyć proces wysyłania, ilekroć widok uruchamia akcję wysyłania. Jeśli zrobisz to poprawnie, zawsze możesz łatwo znaleźć drogę do sieci MVC lub aplikacji lokalnej. Niezależnie od tego, czy jest to komputer stacjonarny czy strona internetowa (na kliencie), kontroler powinien obsłużyć proces wysyłania, ilekroć widok uruchamia akcję wysyłania. Jeśli zrobisz to poprawnie, zawsze możesz łatwo znaleźć drogę do sieci MVC lub aplikacji lokalnej. Niezależnie od tego, czy jest to komputer stacjonarny czy strona internetowa (na kliencie), kontroler powinien obsłużyć proces wysyłania, ilekroć widok uruchamia akcję wysyłania. Jeśli zrobisz to poprawnie, zawsze możesz łatwo znaleźć drogę do sieci MVC lub aplikacji lokalnej.

MVVM jest osobiście moim ulubionym, ponieważ jest całkowicie reaktywny. Jeśli stan modelu zmienia się, ViewModel nasłuchuje i tłumaczy ten stan i to wszystko !!! Widok następnie nasłuchuje ViewModel w celu zmiany stanu, a także aktualizuje się na podstawie tłumaczenia z ViewModel. Niektórzy nazywają to czystym MVVM, ale tak naprawdę jest tylko jeden i nie obchodzi mnie, jak się z tym kłócisz, i zawsze jest to czysty MVVM, w którym widok nie zawiera absolutnie żadnej logiki.

Oto mały przykład: Powiedzmy, że chcesz, aby menu wsuwało się po naciśnięciu przycisku. W MVC będziesz mieć akcję MenuPressed w swoim interfejsie. Kontroler będzie wiedział, kiedy klikniesz przycisk Menu, a następnie powiesz widokowi, aby przesunął się w menu w oparciu o inną metodę interfejsu, taką jak SlideMenuIn. Z jakiego powodu podróż w obie strony? Incase Kontroler decyduje, że nie możesz lub chce zrobić coś innego, dlatego właśnie. Kontroler powinien być odpowiedzialny za Widok, gdy Widok nic nie robi, chyba że Administrator tak mówi. JEDNAK; w MVVM menu slajdów w animacji powinno być wbudowane i ogólne, a zamiast być poproszony o włączenie, zrobi to na podstawie pewnej wartości. Więc nasłuchuje ViewModel, a gdy ViewModel mówi, IsMenuActive = true (lub jakkolwiek) animacja, która ma miejsce. Teraz, Powiedziawszy to, chcę powiedzieć jeszcze raz, NAPRAWDĘ JASNE i PROSZĘ zwrócić uwagę. IsMenuActive jest prawdopodobnie BAD MVVM lub ViewModel. Projektując ViewModel, nigdy nie należy zakładać, że Widok będzie miał w ogóle jakieś funkcje i po prostu przekaże przetłumaczony stan modelu. W ten sposób, jeśli zdecydujesz się zmienić widok, aby usunąć menu i po prostu pokazać dane / opcje w inny sposób, ViewModel nie ma znaczenia. Jak więc zarządzałbyś menu? Kiedy dane mają sens, właśnie tak. Jednym ze sposobów jest udostępnienie Menu listy opcji (prawdopodobnie tablicy wewnętrznych modeli ViewModels). Jeśli ta lista zawiera dane, menu wie, że można otworzyć za pomocą wyzwalacza, jeśli nie, to wie, że można ukryć za pomocą wyzwalacza. Po prostu masz dane dla menu lub nie w ViewModel. NIE decyduj się na pokazywanie / ukrywanie tych danych w ViewModel. po prostu przetłumacz stan modelu. W ten sposób widok jest całkowicie reaktywny i ogólny i może być używany w wielu różnych sytuacjach.

Wszystko to prawdopodobnie nie ma absolutnie żadnego sensu, jeśli nie znasz już co najmniej architektury każdego z nich, a nauka może być bardzo myląca, ponieważ w sieci znajdziesz DUŻO ZŁEJ informacji.

Więc ... rzeczy, o których należy pamiętać, aby zrobić to dobrze. Zdecyduj z wyprzedzeniem, jak zaprojektować swoją aplikację i PRZYKLEJ.

Jeśli korzystasz z MVC, co jest świetne, upewnij się, że kontrolerem można zarządzać i mieć pełną kontrolę nad swoim widokiem. Jeśli masz duży widok, rozważ dodanie do niego elementów sterujących, które mają różne kontrolery. PO PROSTU NIE kaskaduj tych kontrolerów z różnymi kontrolerami. Bardzo frustrujące w utrzymaniu. Poświęć chwilę i zaprojektuj wszystko osobno w taki sposób, aby działało ono jako osobne komponenty ... I zawsze pozwól Kontrolerowi powiedzieć Modelowi, aby zatwierdził lub utrzymał pamięć. Idealną konfiguracją zależności dla MVC w jest Widok ← Kontroler → Model lub ASP.NET (nie zaczynaj mnie) Model ← Widok ↔ Kontroler → Model (gdzie Model może być taki sam lub zupełnie inny Model od Kontrolera do Widoku) ... oczywiście jedyną potrzebną wiedzą na temat Kontrolera w Widoku w tym momencie jest głównie odniesienie do punktu końcowego, aby wiedzieć, gdzie z powrotem przekazać model.

Jeśli wykonujesz MVVM, błogosławię twoją uprzejmą duszę, ale poświęć trochę czasu, aby zrobić to PRAWO! Nie używaj interfejsów dla jednego. Pozwól, aby Twój widok decydował o tym, jak będzie wyglądać na podstawie wartości. Graj z widokiem z próbnymi danymi. Jeśli w końcu zobaczysz widok, który pokazuje menu (jak w przykładzie), nawet jeśli nie chciałeś go wtedy, to DOBRY. Twój widok działa tak, jak powinien i reaguje w oparciu o wartości, jak powinien. Wystarczy dodać kilka dodatkowych wymagań do wyzwalacza, aby upewnić się, że tak się nie stanie, gdy ViewModel jest w konkretnym przetłumaczonym stanie lub wydać polecenie ViewModel, aby opróżnić ten stan. W swoim ViewModel NIE usuwaj tego z wewnętrzną logiką, tak jakbyś decydował stamtąd, czy widok powinien to zobaczyć. Pamiętaj, że nie możesz zakładać, że w ViewModel jest menu. I w końcu, Model powinien po prostu pozwalać na zmianę i najprawdopodobniej stan sklepu. To tutaj nastąpi walidacja i wszystko; na przykład, jeśli model nie może zmodyfikować stanu, po prostu oznaczy się jako brudny lub coś w tym rodzaju. Kiedy ViewModel zda sobie z tego sprawę, przetłumaczy to, co jest brudne, a następnie View zda sobie z tego sprawę i pokaże pewne informacje za pośrednictwem innego wyzwalacza. Wszystkie dane w Widoku można powiązać z ViewModel, więc wszystko może być dynamiczne tylko Model i ViewModel absolutnie nie ma pojęcia o tym, jak Widok zareaguje na powiązanie. W rzeczywistości Model nie ma też pojęcia o ViewModel. Podczas konfigurowania zależności powinny wskazywać tak i tylko tak t zmodyfikuj stan, a następnie oznaczy się jako brudny lub coś takiego. Kiedy ViewModel zda sobie z tego sprawę, przetłumaczy to, co jest brudne, a następnie View zda sobie z tego sprawę i pokaże pewne informacje za pośrednictwem innego wyzwalacza. Wszystkie dane w Widoku można powiązać z ViewModel, więc wszystko może być dynamiczne tylko Model i ViewModel absolutnie nie ma pojęcia o tym, jak Widok zareaguje na powiązanie. W rzeczywistości Model nie ma też pojęcia o ViewModel. Podczas konfigurowania zależności powinny wskazywać tak i tylko tak t zmodyfikuj stan, a następnie oznaczy się jako brudny lub coś takiego. Kiedy ViewModel zda sobie z tego sprawę, przetłumaczy to, co jest brudne, a następnie View zda sobie z tego sprawę i pokaże pewne informacje za pośrednictwem innego wyzwalacza. Wszystkie dane w Widoku można powiązać z ViewModel, więc wszystko może być dynamiczne tylko Model i ViewModel absolutnie nie ma pojęcia o tym, jak Widok zareaguje na powiązanie. W rzeczywistości Model nie ma też pojęcia o ViewModel. Podczas konfigurowania zależności powinny wskazywać tak i tylko tak Wszystkie dane w Widoku można powiązać z ViewModel, więc wszystko może być dynamiczne tylko Model i ViewModel absolutnie nie ma pojęcia o tym, jak Widok zareaguje na powiązanie. W rzeczywistości Model nie ma też pojęcia o ViewModel. Podczas konfigurowania zależności powinny wskazywać tak i tylko tak Wszystkie dane w Widoku można powiązać z ViewModel, więc wszystko może być dynamiczne tylko Model i ViewModel absolutnie nie ma pojęcia o tym, jak Widok zareaguje na powiązanie. W rzeczywistości Model nie ma też pojęcia o ViewModel. Podczas konfigurowania zależności powinny wskazywać tak i tylko takWidok → ViewModel → Model (i notatka boczna tutaj ... i to zapewne będzie również przedmiotem sporu, ale mnie to nie obchodzi ... NIE PRZEKAZAJ MODELU WIDOKU, chyba że MODEL jest niezmienny; w przeciwnym razie owiń go właściwy ViewModel. Widok nie powinien widzieć okresu modelowania. Szczurom daję znać, jakie demo widziałeś lub jak to zrobiłeś, to źle.)

Oto moja ostatnia wskazówka ... Spójrz na dobrze zaprojektowaną, ale bardzo prostą aplikację MVC i zrób to samo dla aplikacji MVVM. Jeden będzie miał większą kontrolę z ograniczoną do zera elastycznością, podczas gdy drugi nie będzie miał kontroli i nieograniczonej elastyczności.

Kontrolowane środowisko jest dobre do zarządzania całą aplikacją z zestawu kontrolerów lub (z jednego źródła), podczas gdy środowisko reaktywne można podzielić na osobne repozytoria, absolutnie nie mając pojęcia, co robi reszta aplikacji. Zarządzanie mikro a zarządzanie bezpłatne.

Jeśli nie pomyliłem cię wystarczająco, spróbuj się ze mną skontaktować ... Nie mam nic przeciwko omówieniu tego szczegółowo z ilustracjami i przykładami.

Pod koniec dnia wszyscy jesteśmy programistami i ta anarchia żyje w nas podczas kodowania ... Więc zasady zostaną złamane, teorie się zmienią, a wszystko to skończy się praniem świń ... Ale podczas pracy nad dużymi w projektach i w dużych zespołach naprawdę pomaga uzgodnić wzór projektowy i go egzekwować. Pewnego dnia małe dodatkowe kroki podjęte na początku staną się skokami i granicami oszczędności później.


Niezwykle szczegółowa i dokładna odpowiedź! Uczyniło mnie to krystalicznie czystym. :-)
ankush981

„nauka tego może być bardzo myląca, ponieważ w sieci znajdziesz DUŻO ZŁYCH informacji”. Tak. Jako ktoś, kto wydaje się mieć duże doświadczenie z tymi wzorami projektowymi, czy znasz jakieś dobre tutoriale / przewodniki?
MarredCheese

1
Szczerze mówiąc, moja wiedza na temat MVVM trwała lata lub próby i błędy i wykorzystywałem / robiłem to na różne sposoby w oparciu o wysiłki zespołu. Niedawno (2 lata temu) mogłem wykorzystać moje własne doświadczenie w podsumowanym planie gry i poprowadzić zespół do końca, a my odnieśliśmy ogromny sukces. To powiedziawszy, nie mogę skierować cię w żadne miejsce i przepraszam. Mogę powiedzieć, że masz rację, z powodu różnych opinii jest to bardzo mylące, ale IMO w przypadku MVVM ma być jak najbardziej ogólne. Spraw, aby ViewModels umożliwiał widokom łączenie i pracę z danymi ściśle, ale W JAKIMKOLWIEK widoku ...
Michael Puckett II,

1
Innymi słowy NIGDY nie zmuszaj ViewModel do zakładania, że ​​Widok będzie wyglądał lub działał w jakikolwiek sposób. Moim zdaniem ViewModel najlepiej nadaje się jako interfejs API, ale przy ścisłej komunikacji. Postępuj zgodnie z planem gry, aby powiązać, edytować, wydawać polecenia itp. Jeśli widok potrzebuje dodatkowej logiki do działania w określony sposób, która nie ma nic wspólnego z aplikacją lub danymi (np. Animacją lub listą rozwijaną ...), to ta logika jakoś należy do warstwy Widok. Znów jest mnóstwo opinii i to tylko moje, ale mam tutaj dobre doświadczenie i solidne osiągnięcia.
Michael Puckett II

Mam przykładowe aplikacje, których nie mam nic przeciwko udostępnianiu i które nie miałyby nic przeciwko skonfigurowaniu prostego programu i powiedzę tobie lub komukolwiek innemu, jeśli będzie chciał lub ciekawy.
Michael Puckett II,

23

Prosta różnica: (zainspirowany kursem Yaakova Coursera AngularJS)

wprowadź opis zdjęcia tutaj

MVC (kontroler widoku modelu)

  1. Modele: modele zawierają informacje o danych. Nie dzwoni ani nie używa kontrolera i widoku. Zawiera logikę biznesową i sposoby reprezentacji danych. Niektóre z tych danych, w jakiejś formie, mogą być wyświetlane w widoku. Może także zawierać logikę do pobierania danych z jakiegoś źródła.
  2. Kontroler: Działa jako połączenie między widokiem a modelem. Wyświetl połączenia Kontroler i kontroler wywołuje model. Zasadniczo informuje model i / lub widok, aby odpowiednio zmienić.
  3. Zobacz: Oferty z częścią interfejsu użytkownika. Interakcja z użytkownikiem.

MVVM (widok modelu Zobacz model)

ViewModel :

  1. Jest to reprezentacja stanu widoku.
  2. Przechowuje dane wyświetlane w widoku.
  3. Odpowiada na wyświetlanie zdarzeń, czyli logikę prezentacji.
  4. Wywołuje inne funkcje przetwarzania logiki biznesowej.
  5. Nigdy bezpośrednio nie prosi widoku o wyświetlenie czegokolwiek.

18

MVVM jest udoskonaleniem (dyskusyjnym) wzorca modelu prezentacji . Mówię, że można dyskutować, ponieważ jedyna różnica polega na tym, jak WPF zapewnia możliwość wiązania danych i obsługi poleceń.


1
W 2009 r. Ta odpowiedź była prawdopodobnie dobra, ale dziś nie ma debaty, ponieważ nawet formanty Pomocnika HTML z MSFT pozwalają na wiązanie przy użyciu niesławnych pomocników „Dla”. Knockout polega na wiązaniu danych po stronie klienta.
John Peters

1
Stwierdziłem to w 2009 r., Ponieważ zbyt wiele osób w społeczności zaakceptowało tę odpowiedź. Powiedziałem, że jest to dyskusyjne, ponieważ MVVM i Model prezentacji naprawdę mają ten sam wzór pod różnymi nazwami. Ze względu na popularność WPF, w dzisiejszych czasach często jest nazywany MVVM, ale obie nazwy są dokładne.
wekempf

15

Viewmodel jest „abstrakcyjnym” modelem elementów interfejsu użytkownika. Musi umożliwiać wykonywanie poleceń i działań w twoim widoku w sposób niewizualny (na przykład w celu przetestowania).

Jeśli pracowałeś z MVC, prawdopodobnie kiedyś przydało ci się tworzenie obiektów modelowych odzwierciedlających stan twojego widoku, na przykład do pokazywania i ukrywania niektórych okien dialogowych edycji itp. W takim przypadku używasz modelu widoku.

Wzorzec MVVM jest po prostu uogólnieniem tej praktyki na wszystkie elementy interfejsu użytkownika.

I nie jest to wzorzec Microsoft, ale dołącza się to, że powiązania danych WPF / Silverlight są szczególnie dobrze przystosowane do pracy z tym wzorcem. Ale nic nie stoi na przeszkodzie, aby na przykład używać go z twarzami serwera Java.


13

Inne odpowiedzi mogą nie być łatwe do zrozumienia dla osoby, która nie zna dobrze wzorów architektonicznych. Ktoś, kto jest nowy w architekturze aplikacji, może chcieć wiedzieć, w jaki sposób jego wybór może wpłynąć na jej aplikację w praktyce i o co tyle zamieszania w społecznościach.

Próbując rzucić nieco światła na powyższe, wymyśliłem ten scenariusz z udziałem MVVM, MVP i MVC. Historia zaczyna się od kliknięcia przez użytkownika przycisku „ZNAJDŹ” w wyszukiwarce filmów…:

Użytkownik: kliknij…

Zobacz : Kto to jest? [ MVVM | MVP | MVC ]

Użytkownik: Właśnie kliknąłem przycisk wyszukiwania…

Widok : Ok, poczekaj chwilę… [ MVVM | MVP | MVC ]

( Zobacz wywoływanie ViewModel | Prezenter | Kontroler …) [ MVVM | MVP | MVC ]

Widok : Hej ViewModel | Prezenter | Kontrolerze , użytkownik właśnie kliknął przycisk wyszukiwania, co mam zrobić? [ MVVM | MVP | MVC ]

ViewModel | Prezenter | Kontroler : Hey Zobacz , czy jest jakiś termin wyszukiwania na tej stronie? [ MVVM | MVP | MVC ]

Widok : Tak,… tutaj jest… „fortepian” [ MVVM | MVP | MVC ]

—— Jest to najważniejsza różnica między MVVM I MVP | MVC ———

Prezenter : Dzięki Widok ,… tymczasem szukam wyszukiwanego hasła w Modelu , pokaż mu pasek postępu [ MVP | MVC ]

( Prezenter | Kontroler dzwoni do modelu …) [ MVP | MVC ]

ViewController : Dzięki, sprawdzę wyszukiwane hasło w Modelu, ale nie zaktualizuję cię bezpośrednio. Zamiast tego wywołam zdarzenia w searchResultsListObservable, jeśli wystąpi jakikolwiek wynik. Więc lepiej to obserwuj. [ MVVM ]

(Obserwując dowolny wyzwalacz w searchResultsListObservable, widok uważa, że ​​powinien pokazywać użytkownikowi pasek postępu, ponieważ ViewModel nie chce z nim rozmawiać)

—————————————————————————————

ViewModel | Prezenter | Kontroler : Hej, model , czy pasujesz do tego wyszukiwanego terminu ?: „piano” [ MVVM | MVP | MVC ]

Model : Hej ViewModel | Prezenter | Kontroler , pozwól mi sprawdzić… [ MVVM | MVP | MVC ]

( Model wykonuje zapytanie do bazy danych filmów…) [ MVVM | MVP | MVC ]

( Po chwili … )

———— To jest punkt rozbieżności między MVVM , MVP i MVC ————–

Model : Znalazłem dla ciebie listę, ViewModel | Prezenter , tutaj jest w JSON „[{„ name ”:„ Piano Teacher ”,„ year ”: 2001}, {„ name ”:„ Piano ”,„ year ”: 1993}]” [ MVVM | MVP ]

Model : Dostępne są wyniki, Kontroler. Utworzyłem zmienną pola w moim wystąpieniu i wypełniłem ją wynikiem. Nazywa się „searchResultsList” [ MVC ]

( Prezenter | Kontroler dziękuje Modelowi i wraca do Widoku ) [ MVP | MVC ]

Prezenter : Dzięki za czekanie. Widok , znalazłem dla ciebie listę pasujących wyników i uporządkowałem je w możliwym do przedstawienia formacie: [„Piano Teacher 2001 ″,” Piano 1993 ”]. Teraz też ukryj pasek postępu [ MVP ]

Kontroler : Dzięki za czekanie. Widok , poprosiłem model o zapytaniu. Mówi, że znalazł listę pasujących wyników i zapisał je w zmiennej o nazwie „searchResultsList” wewnątrz swojej instancji. Możesz go zdobyć stamtąd. Teraz też ukryj pasek postępu [ MVC ]

ViewModel : Każdy obserwator w searchResultsListObservable powinien zostać powiadomiony, że istnieje nowa lista w formacie do prezentacji: [„Piano Teacher 2001 ″,” Piano 1993 ”]. [ MVVM ]

Zobacz : Bardzo dziękuję Prezenterowi [ MVP ]

Widok : Dziękuję „ Kontroler ” [ MVC ] (teraz widok sam siebie zadaje pytanie: w jaki sposób mam przedstawić użytkownikowi wyniki uzyskane z modelu ? Czy rok produkcji filmu powinien być pierwszy czy ostatni…?)

Widok : Och, w searchResultsListObservable jest nowy wyzwalacz… dobrze, jest lista do zaprezentowania, teraz muszę tylko pokazać ją na liście. Powinienem też ukryć pasek postępu, skoro mam już wynik. [ MVVM ]

W przypadku zainteresowania, napisałem szereg artykułów tutaj , porównując MVVM, MVP i MVC poprzez wdrożenie film szukać Android app.


Tutaj jest świetna odpowiedź pod całym tekstem smakowym ... Przy odrobinie formatowania i krótkiej rozmowie między komponentami może to być najlepszy na tej stronie.
neonblitzer

10

Wstrzykiwanie silnie wpisanych modeli ViewModels do widoku za pomocą MVC

  1. Kontroler jest odpowiedzialny za odświeżenie ViewModel i wstrzyknięcie go do widoku. (dla otrzymywania wniosków)
  2. ViewModel jest kontenerem dla DataContext i stanu widoku, takiego jak ostatnio wybrany element itp.
  3. Model zawiera jednostki DB i jest bardzo zbliżony do schematu DB, wykonuje zapytania i filtruje. (Podoba mi się w tym EF i LINQ)
  4. Model powinien również uwzględniać repozytoria i / lub prognozowanie wyników na silne typy (EF ma świetną metodę ... EF.Database.Select (querystring, parms) dla bezpośredniego dostępu ADO do wstrzykiwania zapytań i odzyskiwania silnych typów. To dotyczy EF jest powolnym argumentem. EF NIE jest WOLNY !
  5. ViewModel pobiera dane oraz wykonuje reguły biznesowe i weryfikację
  6. Kontroler po wysłaniu zwrotnym obliczy metodę ViewModel Post i poczeka na wyniki.
  7. Kontroler wstrzykuje nowo zaktualizowany Viewmodel do widoku. Widok używa tylko silnego wiązania typu .
  8. Widok jedynie renderuje dane i wysyła zdarzenia z powrotem do kontrolera. (patrz przykłady poniżej)
  9. MVC przechwytuje żądanie przychodzące i kieruje je do właściwego kontrolera o silnym typie danych

W tym modelu nie ma już kontaktu na poziomie HTTP z obiektami żądania lub odpowiedzi, ponieważ maszyna MVC MSFT ukrywa je przed nami.

W wyjaśnieniu do pkt 6 powyżej (na żądanie) ...

Załóżmy ViewModel w ten sposób:

public class myViewModel{
     public string SelectedValue {get;set;}
public void Post(){
    //due to MVC model binding the SelectedValue string above will be set by MVC model binding on post back.
    //this allows you to do something with it.
    DoSomeThingWith(SelectedValue);
    SelectedValue = "Thanks for update!";
 }
}

Metoda kontrolera posta będzie wyglądać następująco (patrz poniżej), zauważ, że wystąpienie mvm jest automatycznie inicjowane przez mechanizmy wiązania MVC. W rezultacie nigdy nie musisz zejść do warstwy ciągu zapytania! To jest MVC tworzący dla Ciebie ViewModel na podstawie ciągów zapytań!

[HTTPPOST]   
public ActionResult MyPostBackMethod (myViewModel mvm){
         if (ModelState.IsValid)
        {
               // Immediately call the only method needed in VM...
               mvm.Post()
        }
      return View(mvm);
}

Pamiętaj, że aby powyższa metoda działania działała zgodnie z Twoimi zamierzeniami, musisz mieć zdefiniowany pusty CTOR, który zainicjalizuje rzeczy, które nie zostały zwrócone w poście. Zwrot musi również zaksięgować pary nazwa / wartość dla tych rzeczy, które uległy zmianie. Jeśli brakuje par nazwa-wartość, silnik wiązania MVC robi to, co jest po prostu niczym! Jeśli tak się zdarzy, możesz powiedzieć, że „tracę dane na postach”…

Zaletą tego wzorca jest to, że ViewModel wykonuje wszystkie „bałagany”, współpracując z logiką Model / Biznes, kontroler jest jedynie swego rodzaju routerem. To jest SOC w akcji.


Czy możesz wyjaśnić punkt 6? Zdaję sobie sprawę, że obejmujesz tylko ASP.Net, ale wydaje się, że dodaje niepożądaną zależność do ViewModel. (np. wiedza o tym, skąd dane pochodzą / do których pochodzą). Przykład kodu (pseudo-kod?) Dobrze byłoby wyjaśnić tę odpowiedź i pokazać, które części są po stronie serwera, a które po stronie klienta.
Gone Coding

9

MVVM dodaje model widoku do miksu. Jest to ważne, ponieważ pozwala na zastosowanie wielu wiążących podejść WPF, bez umieszczania wszystkich elementów specyficznych dla interfejsu użytkownika w zwykłym modelu.

Mogę się mylić, ale nie jestem pewien, czy MVVM naprawdę zmusza kontroler do miksu. Uważam, że koncepcja jest bardziej zgodna z: http://martinfowler.com/eaaDev/PresentationModel.html . Myślę, że ludzie decydują się na połączenie go z MVC, nie dlatego, że jest to wbudowane we wzór.


3
Ściśle mówiąc, MVVM jest modelem prezentacji, chociaż MVVM staje się preferowaną nazwą dla realizacji wzorca dla WPF.
wekempf

Zgoda. Viewmodel w MVC „JEST” automatem stanowym dla widoku. Zawiera tekst i śledzi wszystkie informacje o wybranych elementach, a także może zawierać całą logikę sprawdzania poprawności za pomocą interfejsu IValidatableObject. ViewModel łączy się z DB w warstwie modelu, która może wykorzystywać modele silnie typowane. MVVM w WPF JEST kontrolerem MVC. Ale kontroler MVC jest znacznie czystszy, jest niezbędny do obsługi routingu.
John Peters

9

Z tego, co mogę powiedzieć, MVVM odwzorowuje na MV MVC - co oznacza, że ​​w tradycyjnym wzorze MVC V nie komunikuje się bezpośrednio z M. W drugiej wersji MVC istnieje bezpośrednie połączenie między M i V. MVVM wydaje się brać wszystkie zadania związane z komunikacją M i V i łączyć je w celu oddzielenia od C. W efekcie nadal istnieje przepływ pracy aplikacji o większym zakresie (lub implementacja scenariuszy użytkowania), które nie są w pełni uwzględnione w MVVM. To jest rola kontrolera. Usuwając te aspekty niższego poziomu z kontrolerów, są one czystsze i ułatwiają modyfikowanie scenariusza użytkowania aplikacji i logiki biznesowej, dzięki czemu kontrolery są bardziej przydatne do ponownego użycia.


1
IMHO Twierdzę, że „uczynienie kontrolerów bardziej użytecznymi” jest zbyt szerokim stwierdzeniem i przynosi efekt przeciwny do zamierzonego dla ogólnych „kontrolerów” ASP.Net (tj. Nie warstwy logiki biznesowej), ponieważ te kontrolery zwykle zawierają części aplikacji, które są aplikacjami specyficzne . To Widoki, Modele, Modele View i logika biznesowa muszą być wielokrotnego użytku. Myślałem, że traktowanie modułów logiki biznesowej jako dostawców usług, a nie kontrolerów, byłoby lepszym rozwiązaniem.
Gone Coding

Ale mówisz o „ViewModel” w Asp.net, a nie o wzorcu projektowym MVVM. Dwie różne rzeczy.
Luis

9

Zaskakuje mnie, że to głosowanie, na które głosowano, nie wspominając o pochodzeniu MVVM. MVVM jest popularnym terminem używanym w społeczności Microsoft i pochodzi z modelu prezentacji Martina Fowlera . Aby zrozumieć motyw wzoru i różnice z innymi, najpierw należy przeczytać oryginalny artykuł o wzorze.


Wow ... więc zarówno MVC, jak i MVVM pochodzą z SmallTalk? Najwyraźniej wyprzedzili swój czas ...
MattE,

W rzeczywistości stwierdzenie, że pochodzi z modelu prezentacji Martina Fowlera, nie jest dokładne. Bardzo trudno jest ustalić, który był pierwszy, ale oba wzorce (pozwalając na to, że są naprawdę takie same) zostały ustalone niezależnie i mniej więcej w tym samym czasie.
wekempf

6

Cóż, ogólnie MVC jest używany do tworzenia stron internetowych, a MVVM jest najbardziej popularny w rozwoju WPF / Silverlight. Czasami jednak architekt WWW może mieć mieszankę MVC i MVVM.

Na przykład: możesz użyć knockout.js iw tym przypadku będziesz mieć MVVM po stronie klienta. Po stronie serwera MVC można również zmienić. W złożonych aplikacjach nikt nie używa czystego Modelu. Może mieć sens użycie ViewModel jako „Modelu” MVC, a twój prawdziwy model będzie w zasadzie częścią tej maszyny wirtualnej. Daje to dodatkową warstwę abstrakcji.


To, co „tworzenie stron internetowych” oznacza „MVC”, jest niczym innym jak oddzieleniem obaw, a nie autentycznym MVC poprzedzającym sieć.
Terrence Brannon

4

MVVMC, a może MVC +, wydaje się być realnym podejściem zarówno dla przedsiębiorstw, jak i szybkiego opracowywania aplikacji. Chociaż miło jest oddzielić interfejs użytkownika od logiki biznesowej i interakcji, „czysty” wzorzec MVVM i większość dostępnych przykładów najlepiej działa w pojedynczych widokach.

Nie jestem pewien co do twoich projektów, ale większość moich aplikacji zawiera jednak strony i kilka (wielokrotnego użytku) widoków, dlatego też ViewModels muszą do pewnego stopnia współdziałać. Użycie strony jako kontrolera całkowicie zniweczyłoby cel MVVM, więc niestosowanie podejścia „VM-C” dla logiki leżącej u jej podstaw może spowodować… no cóż… trudne konstrukcje w miarę dojrzewania aplikacji. Nawet w VB-6 większość z nas prawdopodobnie przestała kodować logikę biznesową w zdarzeniu Button i zaczęła „przekazywać” polecenia do kontrolera, prawda? Niedawno przyjrzałem się wielu nowym ramkom na ten temat; moim ulubionym jest wyraźnie podejście Magellana (w codeplex). Miłego kodowania!

http://en.wikipedia.org/wiki/Model_View_ViewModel#References


4

Kontroler nie jest zastępowany przez ViewModel w MVVM, ponieważ ViewModel ma zupełnie inną funkcjonalność niż kontroler. Nadal potrzebujesz kontrolera, ponieważ bez kontrolera Twój model, ViewModel i View nie zrobią wiele ... W MVVM masz również kontroler, nazwa MVVM jest po prostu myląca.

MVVMC to poprawne imię w mojej skromnej opinii.

Jak widać ViewModel jest tylko dodatkiem do wzoru MVC. Przenosi logikę konwersji (na przykład konwersję obiektu na ciąg) z kontrolera do ViewModel.


4

Zrobiłem w tym celu artykuł Medium.

MVVM

  1. Zobacz ➡ ViewModel ➡ Model

    • Widok ma odniesienie do ViewModel, ale nie odwrotnie.
    • ViewModel ma odniesienie do modelu, ale nie odwrotnie.
    • Widok nie ma odniesienia do modelu i odwrotnie.
  2. Jeśli używasz kontrolera, może on mieć odniesienie do widoków i modeli ViewModels , chociaż kontroler nie zawsze jest konieczny, jak pokazano w SwiftUI .

  3. Wiązanie danych : tworzymy detektory właściwości ViewModel.
class CustomView: UIView {
  var viewModel = MyViewModel {
    didSet {
      self.color = viewModel.color
    }
  }

  convenience init(viewModel: MyViewModel) {
    self.viewModel = viewModel
  }
}


struct MyViewModel {
   var viewColor: UIColor {
      didSet {
         colorChanged?() // This is where the binding magic happens.
      }
   }

   var colorChanged: ((UIColor) -> Void)?
}


class MyViewController: UIViewController {

   let myViewModel = MyViewModel(viewColor: .green)
   let customView: CustomView!

   override func viewDidLoad() {
      super.viewDidLoad()

      // This is where the binder is assigned.
      myViewModel.colorChanged = { [weak self] color in 
        print("wow the color changed")
      }
      customView = CustomView(viewModel: myViewModel)
      self.view = customView
   }
}

różnice w konfiguracji

  1. Logika biznesowa jest utrzymywana w kontrolerze dla MVC i ViewModels dla MVVM.
  2. Zdarzenia są przekazywane bezpośrednio z widoku do kontrolera w MVC, podczas gdy zdarzenia są przekazywane z widoku do ViewModel do kontrolera (jeśli taki istnieje) dla MVVM.

Wspólne cechy

  1. Zarówno MVVM, jak i MVC nie pozwalają Viewowi wysyłać wiadomości bezpośrednio do Modelu / ów.
  2. Oba mają modele.
  3. Oba mają widoki.

Zalety MVVM

  1. Ponieważ ViewModels posiadają logikę biznesową, są to mniejsze obiekty betonowe, co ułatwia ich testowanie jednostkowe. Z drugiej strony w MVC logika biznesowa znajduje się w ViewController. Jak możesz ufać, że test jednostkowy kontrolera widoku jest całkowicie bezpieczny bez jednoczesnego testowania wszystkich metod i detektorów? Nie można całkowicie ufać wynikom testów jednostkowych.
  2. W MVVM, ponieważ logika biznesowa jest wysysana ze sterownika do atomowych jednostek ViewModel, rozmiar ViewController zmniejsza się, a to czyni kod ViewController bardziej czytelnym.

Zalety MVC

  1. Zapewnienie logiki biznesowej w kontrolerze zmniejsza potrzebę rozgałęzienia, a zatem bardziej prawdopodobne jest uruchamianie instrukcji w pamięci podręcznej, która jest bardziej wydajna niż enkapsulacja logiki biznesowej w ViewModels.
  2. Zapewnienie logiki biznesowej w jednym miejscu może przyspieszyć proces opracowywania prostych aplikacji, w których testy nie są wymagane. Nie wiem, kiedy testy nie są wymagane.
  3. Zapewnienie logiki biznesowej w ViewController jest łatwiejsze do myślenia dla nowych programistów.

1
Najlepsze wytłumaczenie
p32094

2

Z praktycznego punktu widzenia MVC (Model-View-Controller) jest wzorem. Jednak MVC, gdy jest używany jako ASP.net MVC, w połączeniu z Entity Framework (EF) i „elektronarzędziami” jest bardzo potężnym, częściowo zautomatyzowanym podejściem do przenoszenia baz danych, tabel i kolumn na stronę internetową, zarówno w celu pełnego Tylko operacje CRUD lub R (pobieranie lub odczyt). Przynajmniej gdy korzystałem z MVVM, modele widoków współdziałały z modelami zależnymi od obiektów biznesowych, które z kolei były „ręcznie robione” i po wielu wysiłkach udało się uzyskać modele tak dobre, jak EF daje ”. -of-the-box ”. Z praktycznego punktu widzenia programowania MVC wydaje się dobrym wyborem, ponieważ daje wiele gotowych narzędzi, ale wciąż istnieje możliwość dodania dzwonków i gwizdków.


2

Uzupełniając wiele udzielonych odpowiedzi, chciałem dodać trochę dodatkowej perspektywy z punktu widzenia nowoczesnej strony internetowej po stronie klienta - lub z perspektywy bogatej aplikacji internetowej .

Rzeczywiście, w dzisiejszych czasach proste strony internetowe i większe aplikacje internetowe są zwykle budowane z wieloma popularnymi bibliotekami, takimi jak Bootstrap. Zbudowany przez Steve'a Sandersona Knockout zapewnia obsługę wzorca MVVM, który naśladuje jedno z najważniejszych zachowań we wzorcu: wiązanie danych za pośrednictwem modelu widoku. Przy odrobinie JavaScript można zaimplementować dane i logikę, które można następnie dodać do elementów strony za pomocą prostych data-bindatrybutów HTML, podobnie jak przy użyciu wielu funkcji Bootstrap . Razem te dwie biblioteki same oferują interaktywne treści; a w połączeniu z routingiem takie podejście może dać proste, ale potężne podejście do budowania aplikacji jednostronicowej .

Podobnie nowoczesne frameworki po stronie klienta, takie jak Angular, zgodnie z konwencją wzorują się na wzorcu MVC, ale dodają także usługę. Co ciekawe, jest reklamowany jako Model-View-Whthing (MVW). (Zobacz ten post na temat przepełnienia stosu .)

Ponadto wraz z pojawieniem się progresywnych frameworków internetowych, takich jak Angular 2, obserwujemy zmianę terminologii i być może nowy wzorzec architektoniczny, w którym Komponenty składają się z Widoku lub Szablonu i wchodzą w interakcję z Usługą - z których wszystkie mogą być zawarte w Moduł; i seria modułów składa się na aplikację.


2

Kiedyś myślałem, że MVC i MVVM są takie same. Teraz, dzięki istnieniu Fluxa, mogę odróżnić:

W MVC dla każdego widoku w aplikacji masz model i kontroler, więc nazwałbym to widokiem, widokiem modelu, kontrolerem widoku. Wzór nie mówi, w jaki sposób jeden widok może komunikować się z innym. Dlatego w różnych ramach istnieją różne implementacje. Na przykład istnieją implementacje, w których kontrolery rozmawiają ze sobą, podczas gdy w innych implementacjach występuje inny komponent, który pośredniczy między nimi. Istnieją nawet implementacje, w których modele widoku komunikują się ze sobą, co jest zerwaniem ze wzorem MVC, ponieważ dostęp do modelu widoku powinien uzyskać wyłącznie kontroler widoku.

W MVVM masz również model widoku dla każdego komponentu. Wzorzec nie określa, w jaki sposób, do cholery, widok powinien wpływać na model widoku, dlatego zwykle większość ram tylko zawiera funkcje kontrolera w modelu widoku. Jednak MVVM mówi, że dane modelu widoku powinny pochodzić z modelu, który jest całym modelem, który nie jest świadomy lub niestandardowy dla konkretnego widoku.

Aby zademonstrować różnicę, weźmy wzór Flux. Wzorzec strumienia mówi, jak różne widoki w aplikacji powinny się komunikować. Każdy widok nasłuchuje w sklepie i uruchamia akcje za pomocą programu rozsyłającego. Dyspozytor z kolei informuje wszystkie sklepy o właśnie wykonanej akcji, a sklepy same się aktualizują. Magazyn w Flux odpowiada (ogólnemu) modelowi w MVVM. nie jest niestandardowe dla żadnego konkretnego widoku. Tak więc zwykle, gdy ludzie używają React i Flux, każdy komponent React faktycznie implementuje wzorzec MVVM. Kiedy występuje akcja, model widoku wywołuje dyspozytora, a na koniec jest aktualizowany zgodnie ze zmianami w sklepie, którym jest model. Nie można powiedzieć, że każdy komponent implementuje MVC, ponieważ w MVC tylko kontroler może aktualizować model widoku.


2

mvc jest po stronie serwera, a mvvm po stronie klienta (przeglądarki) podczas tworzenia stron internetowych.

przez większość czasu javascript jest używany do mvvm w przeglądarce. istnieje wiele technologii po stronie serwera dla mvc.


1

W skrócie - w MVC Controler jest świadomy widoku (kontroli), podczas gdy w MVVM ViewModel nie wie, kto go używa. ViewModel udostępnia swoje obserwowalne właściwości i działania każdemu, kto może być zainteresowany jego użyciem. Ten fakt ułatwia testowanie, ponieważ w ViewModel nie ma odniesienia do interfejsu użytkownika.


1

Model – Widok – Kontroler (zwykle znany jako MVC ) to wzorzec projektowy oprogramowania powszechnie stosowany do opracowywania interfejsów użytkownika, które dzielą logikę programu na trzy połączone ze sobą elementy. Odbywa się to w celu oddzielenia wewnętrznych reprezentacji informacji od sposobu, w jaki informacje są przedstawiane i akceptowane przez użytkownika. Zgodnie z wzorcem architektonicznym MVC oddziela te główne komponenty, umożliwiając ponowne użycie kodu i równoległe opracowywanie.

Tradycyjnie stosowany w graficznych interfejsach użytkownika (GUI), wzór ten stał się popularny przy projektowaniu aplikacji internetowych. Popularne języki programowania, takie jak JavaScript, Python, Ruby, PHP, Java i C # mają frameworki MVC, które są używane do tworzenia aplikacji internetowych od razu po wyjęciu z pudełka.

Model

Centralny element wzoru. Jest to dynamiczna struktura danych aplikacji, niezależna od interfejsu użytkownika. Bezpośrednio zarządza danymi, logiką i regułami aplikacji.

Widok

Wszelkie przedstawienie informacji, takich jak wykres, diagram lub tabela. Możliwych jest wiele widoków tej samej informacji, takich jak wykres słupkowy do zarządzania i widok tabelaryczny dla księgowych.

Kontroler

Akceptuje dane wejściowe i konwertuje je na polecenia modelu lub widoku.

Oprócz podziału aplikacji na te komponenty, projekt model-widok-kontroler definiuje interakcje między nimi.

Model odpowiada za zarządzanie danymi aplikacji. Odbiera dane wejściowe od kontrolera.

Widok oznacza prezentację modelu w określonym formacie.

Kontroler reaguje na dane wejściowe użytkownika i wykonuje interakcje na obiektach modelu danych. Sterownik odbiera dane wejściowe, opcjonalnie je weryfikuje, a następnie przekazuje dane wejściowe do modelu. wprowadź opis zdjęcia tutaj

Model – View – ViewModel (MVVM) to wzorzec architektury oprogramowania.

MVVM ułatwia oddzielenie rozwoju graficznego interfejsu użytkownika - czy to za pomocą języka znaczników lub kodu GUI - od rozwoju logiki biznesowej lub logiki zaplecza (modelu danych). Model widoku MVVM jest konwerterem wartości, co oznacza, że ​​model widoku jest odpowiedzialny za eksponowanie (konwersję) obiektów danych z modelu w taki sposób, aby obiekty były łatwo zarządzane i prezentowane. Pod tym względem model widoku jest bardziej modelowy niż widok i obsługuje większość, jeśli nie całą logikę wyświetlania widoku. Model widoku może implementować wzorzec mediatora, organizując dostęp do logiki zaplecza wokół zestawu przypadków użycia obsługiwanych przez widok.

MVVM jest odmianą wzorca projektowego modelu prezentacji Martina Fowlera. MVVM wyodrębnia stan i zachowanie widoku w ten sam sposób, ale Model prezentacji wyodrębnia widok (tworzy model widoku) w sposób niezależny od konkretnej platformy interfejsu użytkownika.

MVVM został wymyślony przez architektów Microsoft Kena Coopera i Teda Petersa specjalnie w celu uproszczenia programowania interfejsów użytkownika na podstawie zdarzeń. Wzorzec został włączony do Windows Presentation Foundation (WPF) (system graficzny Microsoft .NET) i Silverlight (pochodna aplikacji internetowej WPF). John Gossman, jeden z architektów Microsoft WPF i Silverlight, ogłosił MVVM na swoim blogu w 2005 roku.

Model – Widok – ViewModel jest również nazywany segregatorem modelu, szczególnie w implementacjach nieobsługujących platformy .NET. ZK (framework aplikacji WWW napisany w Javie) i KnockoutJS (biblioteka JavaScript) używają spoiwa model-view-binder. wprowadź opis zdjęcia tutaj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.