Czy MVVM jest bezcelowy? [zamknięte]

Czy implementacja MVVM jest bezcelowa? Tworzę nową aplikację i rozważałem Windows Forms i WPF. Wybrałem WPF, ponieważ jest przyszłościowy i oferuje dużą elastyczność. Jest mniej kodu i łatwiej dokonać znaczących zmian w interfejsie użytkownika za pomocą XAML.

Ponieważ wybór dla WPF jest oczywisty, pomyślałem, że równie dobrze mogę przejść całą drogę używając MVVM jako mojej architektury aplikacji, ponieważ oferuje mieszalność, problemy z separacją i testowalność jednostkową. Teoretycznie wydaje się piękny jak Święty Graal programowania UI. Ta krótka przygoda przerodziła się jednak w prawdziwy ból głowy. Zgodnie z oczekiwaniami w praktyce okazuje się, że wymieniłem jeden problem na drugi. Mam tendencję do bycia obsesyjnym programistą, ponieważ chcę robić rzeczy we właściwy sposób, aby uzyskać właściwe wyniki i być może stać się lepszym programistą. Wzór MVVM właśnie oblał mój test na produktywność i właśnie przekształcił się w Wielki yucky hack!

The clear case w punkcie jest dodanie obsługi modalnego okna dialogowego. Poprawnym sposobem jest umieszczenie okna dialogowego i powiązanie go z modelem widoku. Doprowadzenie tego do pracy jest trudne. Aby skorzystać z wzorca MVVM, musisz rozłożyć kod w kilku miejscach na warstwach aplikacji. Musisz również używać ezoterycznych konstrukcji programistycznych, takich jak szablony i wyrażenia lamba. Rzeczy, które sprawiają, że gapisz się na ekran drapiąc się po głowie. To sprawia, że konserwacja i debugowanie to koszmar czekając na to, co niedawno odkryłem. Miałem okno o działa dobrze, dopóki nie dostałem wyjątku po raz drugi wywołałem go, mówiąc, że nie może pokazać okno dialogowe ponownie po jego zamknięciu. Musiałem dodać obsługę zdarzeń dla zamkniętej funkcjonalności do okna dialogowego, kolejny w implementacji IDialogView i wreszcie kolejny w IDialogViewModel. Myślałem, że MVVM uratuje nas przed tak ekstrawaganckim hakerstwem!

Jest kilku ludzi z konkurencyjne rozwiązania tego problemu i wszystkie są hacki i nie zapewniają czyste, łatwe do wielokrotnego użytku, eleganckie rozwiązanie. Większość zestawów narzędzi MVVM przenika okna dialogowe, a gdy je adresują, są to po prostu pola alarmowe, które nie wymagają niestandardowych interfejsów ani modeli widoku.

Planuję zrezygnować z wzorca widoku MVVM, przynajmniej z jego ortodoksyjnej implementacji. Co o tym myślisz? Czy warto było się trudzić, gdybyś miał jakieś? Jestem tylko niekompetentnym programistą czy czy MVVM nie jest tym czym jest?

Author: BoltClock, 2010-05-09

8 answers

Sorry jeśli moja odpowiedź stała się trochę długa, ale nie wiń mnie! Twoje pytanie też jest długie.

Podsumowując, MVVM nie jest bezcelowy.

Oczywistym przypadkiem jest dodanie obsługa modalnego okna dialogowego. Na poprawnym sposobem jest umieszczenie okna dialogowego i powiązać go z modelem widoku. Getting praca jest trudna.

Tak, naprawdę jest.
Jednak MVVM zapewnia sposób na oddzielenie wyglądu interfejsu użytkownika od jego logiki. Noone forces możesz używać go wszędzie, a nikt nie trzyma Broni przy czole, aby stworzyć osobny model widoku dla wszystkiego.

Oto moje rozwiązanie dla tego konkretnego przykładu:
Sposób, w jaki interfejs użytkownika obsługuje określone dane wejściowe, nie należy do firmy ViewModel. Dodałbym kod do widoku .xaml.plik cs, który tworzy instancję okna dialogowego i ustawia tę samą instancję ViewModel (lub coś innego, w razie potrzeby) jako DataContext.

Aby skorzystać ze wzoru MVVM, kod należy rozpowszechniać w kilku miejscach na warstwach aplikacji. Musisz również używać ezoterycznych konstrukcji programistycznych, takich jak szablony i wyrażenia lamba.

Cóż, nie musisz go używać w kilku miejscach. Tak bym to rozwiązał:

  • Dodaj XAML do widoku i nic w .xaml.cs
  • zapis każdej logiki aplikacji (z wyjątkiem rzeczy, które bezpośrednio operowałyby z elementami interfejsu użytkownika) wewnątrz ViewModel
  • cały kod, który powinny być wykonane przez UI, ale nie ma nic wspólnego z logiki biznesowej idzie do .xaml.pliki cs

Myślę, że celem MVVM jest przede wszystkim oddzielenie logiki aplikacji od konkretnego interfejsu użytkownika, co umożliwia łatwą modyfikację (lub całkowitą wymianę) interfejsu użytkownika.
Używam następującej zasady: Widok może wiedzieć i zakładać wszystko, co chce od ViewModel, ale ViewModel nie może wiedzieć nic o widoku.
WPF zapewnia ładny model wiązania, który możesz użyć, aby osiągnąć dokładnie to.

(BTW, szablony i wyrażenia lambda nie są Ezoteryczne, jeśli są używane poprawnie. Ale jeśli nie chcesz, nie używaj ich.)

Rzeczy, które sprawiają, że gapisz się na ekran drapiąc się po głowie.

Tak, znam to uczucie. Dokładnie to, co czułem, gdy po raz pierwszy zobaczyłem MVVM. Ale kiedy już to opanujesz, nie będzie już źle.

Miałem około pudełko działa dobrze ...

Dlaczego wstawiasz ViewModel za skrzynką o? Nie ma sensu.

Większość zestawów narzędzi MVVM przenika okna dialogowe, a gdy je adresują, są to po prostu pola alarmowe, które nie wymagają niestandardowych interfejsów ani modeli widoku.

Tak, ponieważ sam fakt, że element UI znajduje się w tym samym oknie, lub innym oknie, lub okrąża Marsa w tej chwili, nie jest przedmiotem zainteresowania ViewModels.
rozdzielenie obaw

EDIT:

Oto bardzo fajny filmik the którego tytuł to Zbuduj swój własny Framework MVVM . Warto obejrzeć.

 59
Author: Venemo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-04 16:16:15
Doprowadzenie tego do pracy jest trudne. W postanowienie o skorzystaniu z MVVM wzorzec, musisz rozpowszechniać kod w kilku miejscach na całym warstwy aplikacji. Ty również trzeba używać programowania ezoterycznego konstrukcje jak szablony i lamba wyrażenia.

Dla zwykłego modalnego okna dialogowego? Z pewnością robisz coś nie tak - implementacja MVVM nie musi być aż tak złożona.

Biorąc pod uwagę, że jesteś nowy zarówno w MVVM, jak i WPF, prawdopodobnie wszędzie używasz nieoptymalnych rozwiązań i niepotrzebnie komplikujesz sprawy - przynajmniej tak zrobiłem, gdy po raz pierwszy poszedłem do WPF. Upewnij się, że problemem jest naprawdę MVVM, a nie twoja implementacja przed poddaniem się.

MVVM, MVC, Document-View, itp. to stara rodzina wzorów.. Są wady, ale nie ma fatalnych wad tego typu, które opisujesz.

 8
Author: ima,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-09 18:21:31

Problem z dialogami rozwiązuję poprzez oszustwo. My MainWindow implementuje interfejs IWindowServices, który wyświetla wszystkie okna dialogowe specyficzne dla aplikacji. Moje inne Viewmodele mogą następnie zaimportować interfejs usługi (używam MEF, ale można łatwo przekazać interfejs przez konstruktory ręcznie) i użyć go do osiągnięcia tego, co jest konieczne. Na przykład, oto jak wygląda interfejs dla mojej małej aplikacji użytkowej:

//Wrapper interface for dialog functionality to allow for mocking during tests
public interface IWindowServices
{
    bool ExecuteNewProject(NewProjectViewModel model);

    bool ExecuteImportSymbols(ImportSymbolsViewModel model);

    bool ExecuteOpenDialog(OpenFileDialog dialog);

    bool ExecuteSaveDialog(SaveFileDialog dialog);

    bool ExecuteWarningConfirmation(string text, string caption);

    void ExitApplication();
}

To stawia wszystkie okna dialogowe wykonanie w jednym miejscu i może być łatwo przetarte do testów jednostkowych. Podążam za wzorcem, który klient okna dialogowego musi stworzyć odpowiedni ViewModel, który następnie może skonfigurować w razie potrzeby. Blokuje wywołanie Execute, a następnie klient może spojrzeć na zawartość modelu widoku, aby zobaczyć wyniki okna dialogowego.

Bardziej "czysty" projekt MVVM może być ważny dla dużych aplikacji, gdzie potrzebujesz czystszej izolacji i bardziej złożonej kompozycji, ale dla małych i średnich duże aplikacje, myślę, że praktyczne podejście, z odpowiednimi usługami, aby odsłonić wymagane Hooki, jest całkiem wystarczające.

 5
Author: Dan Bryant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-04 05:18:20

Wzorce projektowe są po to, aby ci pomóc, a nie utrudniać. Małą częścią bycia dobrym deweloperem jest wiedza, kiedy "łamać zasady". Jeśli MVVM jest uciążliwy dla zadania i ustaliłeś, że przyszła wartość nie jest warta wysiłku, nie używaj wzorca. Na przykład, jak skomentowały inne plakaty, dlaczego miałbyś przejść przez wszystkie nad głową, aby zaimplementować proste o polu?

Wzorce projektowe nigdy nie miały być dogmatycznie przestrzegane.

 5
Author: RMart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-04 13:53:14

Jestem w trakcie dość skomplikowanego rozwoju MVVM przy użyciu PRISM, więc już musiałem poradzić sobie z tego typu problemami.

Moje osobiste wnioski:

MVVM vs MVC / PopUps & co

  • MVVM jest naprawdę świetnym wzorcem i w większości przypadków całkowicie zastępuje MVC dzięki potężnemu powiązaniu danych w WPF
  • wywołanie warstwy usług bezpośrednio z prezentera jest w większości przypadków legalną implementacją
  • nawet dość skomplikowane scenariusze List /detali może być zaimplementowany przez czysty MVVM dzięki składni {Binding Path=/}
  • niemniej jednak, gdy konieczna jest kompleksowa koordynacja między wieloma widokami, kontroler w obowiązkowej
  • mogą być używane zdarzenia; Stary wzorzec, który implikuje przechowywanie instancji IView (lub AbstractObserver) w kontrolerze, jest przestarzały
  • kontroler może być wstrzykiwany do każdego prezentera przez kontener IOC
  • usługa IEventAggregator Prism jest innym możliwym rozwiązaniem, jeśli tylko użycie kontroler jest wywołujący zdarzenia (w tym przypadku może całkowicie zastąpić kontroler)
  • jeśli widoki mają być dynamicznie tworzone, jest to bardzo dobrze dopasowane zadanie dla kontrolera (w prism kontroler otrzyma injected (IOC) a IRegionManager)
  • modalne okna dialogowe są w większości przestarzałe w nowoczesnych aplikacjach kompozytowych, z wyjątkiem naprawdę blokowania operacji, takich jak obowiązkowe potwierdzenia; w tych przypadkach aktywacja modalna może być abstrakcyjna jako usługa wywołana wewnątrz kontrolera, a realizowane przez wyspecjalizowaną klasę, która pozwala również na zaawansowane testowanie jednostkowe na poziomie prezentacji. Kontroler wywoła na przykład IConfirmationService.RequestConfirmation ("czy jesteś pewien"), które spowoduje wyświetlenie modalnego okna dialogowego w czasie wykonywania i może być łatwo wyśmiewane podczas testowania jednostek
 4
Author: dan ionescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-08 17:21:28

Ponieważ sam wzór MVVM jest świetny. Ale biblioteka kontroli WPF dostarczana z obsługą wiązania danych NET 4.0 jest bardzo ograniczona, jest o wiele lepsza niż WinForm, ale nadal nie wystarcza do bindowalnego MVVM, powiedziałbym, że jego moc wynosi około 30% tego, co jest potrzebne do bindowalnego MVVM.
Bindable MVVM : to interfejs użytkownika, w którym ViewModel jest podłączony z widokiem tylko za pomocą wiązania danych.
Wzorzec MVVM dotyczy reprezentacji obiektu ViewState, nie opisuje sposobu utrzymywania synchronizacji między widokami i ViewModel, w WPF jest to powiązanie danych, ale może to być wszystko. W rzeczywistości możesz użyć wzorca MVVM w dowolnym zestawie narzędzi UI, który obsługuje zdarzenia \ wywołania zwrotne, możesz go używać w czystym WinAPI w WinForms( zrobiłem, i nie jest to dużo więcej pracy z events \ wywołania zwrotne), a nawet możesz go używać w konsoli tekstowej, jak przepisać Norton Commander DoS ' a za pomocą wzorca MVVM.

W skrócie: MVVM nie jest bezcelowe, jest świetne. Biblioteka kontrolna NET 4.0 WPF to kosz.

Oto prosty dowód na Concept ViewModel, którego nie można powiązać w czysty sposób MVVM za pomocą WPF.

public class PersonsViewModel
{
    public IList<Person> PersonList;
    public IList<ColumnDescription> TableColumns;
    public IList<Person> SelectedPersons;
    public Person ActivePerson;
    public ColumnDescription SortedColumn;
}

Nie można DATA bind WPF w DataGrid nagłówków kolumn, nie można DATA bind wybranych wierszy, itp itd, Można albo zrobić to w prosty sposób Kod, lub napisać 200 linii kodu hack XAML dla tych 5 linii najprostszego ViewModel. Możesz sobie tylko wyobrazić, jak sprawy stają się gorsze dzięki złożonym modelom widoku.
Więc odpowiedź brzmi simmple, chyba że piszesz aplikację Hello World, używając bindowalnego MVVM w WPF jest bez sensu. Będziesz spędzał większość czasu na myślenie na hack, aby związać Cię ViewModel. Wiązanie danych jest ładne, ale przygotuj się na powrót do zdarzenia w 70% czasu.

 1
Author: Alex Burtsev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-04 05:18:13

Widziałem ten sam problem z wieloma implementacjami MVVM, jeśli chodzi o (modalne) okna dialogowe. Kiedy patrzę na uczestników wzorca MVVM to mam wrażenie, że czegoś brakuje do zbudowania spójnej aplikacji.

  • widok zawiera określone elementy sterujące GUI i definiuje wygląd interfejsu użytkownika.
  • ViewModel reprezentuje stan i zachowanie prezentacji.
  • Model może być obiektem biznesowym z warstwę domenową lub usługę, która dostarcza niezbędnych danych.

Ale brakuje:

  • Kto tworzy ViewModels?
  • Kto jest odpowiedzialny za obieg pracy aplikacji?
  • Kto pośredniczy między Viewmodelami, gdy muszą się ze sobą komunikować?

Moim podejściem jest wprowadzenie (Use-Case) kontrolera , który jest odpowiedzialny za brakujące punkty. Jak to działa można zobaczyć na WPF Application Framework (WAF) przykładowe aplikacje.

 0
Author: jbe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-09 18:04:26

Nie, to nie jest bezcelowe, ale trudno jest owinąć głowę, mimo że sam wzór jest śmiesznie prosty. Istnieje mnóstwo dezinformacji tam i różne grupy, które walczą o właściwą drogę. Myślę, że z WPF i Silverlight należy użyć MVVM lub będziesz nad kodowania i próby rozwiązania problemów w nowym modelu "Stary" win forms metodologii, która po prostu prowadzi do kłopotów. Tak jest bardziej w Silverlight, ponieważ wszystko musi być asynchroniczne (hacki wokół tego są możliwe, ale powinieneś po prostu wybrać inną platformę).

Sugerowałbym przeczytanie tego artykułu uproszczenie widoku drzewa WPF za pomocą wzorca ViewModel dokładnie, aby zobaczyć, jak MVVM może być dobrze zaimplementowane i pozwalają zmienić swoją mentalność win forms do nowego sposobu myślenia w MVVM. Krótko mówiąc, Gdy chcesz coś zrobić, zastosuj logikę do modelu widoku, a nie widoku. Chcesz wybrać przedmiot? Zmienić ikonę? Don ' t iterate w przypadku elementów UI wystarczy zaktualizować właściwości modeli i pozwolić powiązaniu danych na robienie brudnych rzeczy.

 0
Author: TugboatCaptain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-18 08:10:17