To trochę zadziorne pytanie. Wzorzec MVVM znajduje zastosowanie w światku .NET w aplikacjach WPF/Silverligh (tak BTW, ciekawe czy ktoś jeszcze pracuje w tej technologii) i od niedawna również w mobilno-wieloplatformowym Xamarin FORMS.
Nie będę się zagłębiał w szczegóły wzorca – wszystko można przeczytać na wikipedii. MVVM daje nam przede wszystkim separację warstwy logiki biznesowej od warstwy prezentacyjnej. W przeciwieństwie do tego, co oferowały nam kiedyś narzędzia RAD jak np. Delphi (spoczywaj w pokoju 🙂 ) czy Windows Forms, nie mamy już mieszanki kodu obsługującego akcje GUI z kodem realizującym rzeczywistą logikę.
Otrzymujemy więc:
- Niezależność kodu GUI (Xaml) od reszty, pozwalając innym osobom (np. UX-om) pracować nad tą warstwą aplikacji
- Możliwość napisania testów dla praktycznie całości logiki, czy stosowania TDD
Sytuacja idealna, zawzięcie często broniona przez ortodoksów stosowania MVVM, jest taka, że w klasach code-behind nie ma być nic. Cała logika interakcji jest realizowana przez ViewModel.
Wróćmy jednak do pytania z tematu posta. MVVM – dlaczego nie ?
Dla osób, które już w tej chwili rozmyślają nad bezsensownością tego pytania nadmienię, że nie jestem przeciwnikiem MVVM. Stosuję go w moich aplikacjach. Używam go też w projekcie konkursowym Daj Się Poznać (w WPF i będę również w Xamarin FORMS). Nie namawiam do pisania spaghetti. Mam natomiast kilka przemyśleń w tym temacie i taka jest geneza tego posta.
Ortodoksyjne stosowanie tego wzorca prowadzi często do sytuacji wprost kuriozalnej. Weźmy chociażby kwestię otwarcia okna dialogowego, w sposób nie łamiący założeń wzorca. Zamiast użyć zwykłego ShowDialog(), trzeba napisać pierdyliard linii kodu, zaciemniając w ten sposób bez sensu projekt. Ile ludzi, tyle też metod w jaki sposób to poprawnie zrobić. Wystarczy zerknąć na StackOverflow tutaj lub tutaj. Zdania są nie rzadko nawet podzielone w kwestii co tak naprawdę łamie założenia wzorca a co nie. Podobnie jest też np. z zamykaniem okna.
Brak jednego rozwiązania tak banalnych i podstawowych funkcjonalności powoduje też ogromne problemy, gdy zetkniemy się z czymś takim w legacy code.
Ile razy zmagając się z jakąś operacją, którą łatwo moglibyśmy zrobić w code-behind, rozwiązanie które znajdujemy wymaga albo napisania (jak w przypadku okna dialogowego) sporej ilości kodu albo wręcz gruntownej przebudowy tego co już mamy.
Wspomóc możemy się frameworkami. Nie każdy ma przecież ochotę pisać własne implementacje RelayCommand. Do najpopularniejszych możemy zaliczyć MVVM Light i Prism. Prism jest potężną kobyłą, realizującą wiele zadań poza wspieraniem wzorca MVVM. MVVM Light jest lżejszy i do tego zadania dedykowany. Prism-a specjalnie nie używałem, MVVM Light za to znam całkiem nieźle. Frameworki rzeczywiście mocno ułatwiają pracę, ale nie załatwiają wszystkich problemów.
Ja nie jestem ortodoksem. Nie uważam, że code-behind musi zostać całkowicie czyste. Jeżeli piszę prostą aplikację lub narzędzie, którego okres żywota jest ograniczony owszem używam MVVM (bo dobre praktyki zawsze stosować warto), ale zwracam uwagę głównie na kod, którego przetestowanie jest istotne. Jeżeli coś wymaga zbyt dużo pracy, a nie jest istotne z punktu widzenia testów – olewam.
W złożonym systemie, który będzie istotnym narzędziem w środowisku produkcyjnym klienta i trzeba go będzie przez jakiś czas supportować, testy mają jednak dużo większą wagę. Nie mniej jednak pewne operacje związane z obsługą widoku, których testowanie nie ma specjalnie sensu robię po prostu tak, żeby było wygodnie. Nie zastanawiam się godzinami czy rozwiązanie, które przyjąłem łamie założenia MVVM czy nie.
Dlaczego tak ? Bo wzorce są przecież po to, żeby zestandaryzować pewne rozwiązania – a co za tym idzie ułatwić pracę. Podążanie dobrze wydeptaną i sprawdzoną drogą jest pewne i bezpieczne. Gorzej, gdy wzorzec nakreśla nam pewien zakres, który jest w pewnych kwestiach wolno interpretowalny, albo wprost – dodaje nam niczym nie uzasadnionej i bezsensownej roboty. Czy warto wtedy kruszyć kopię ? Moim zdaniem nie.
A co Ty o tym myślisz ? Chętnie podyskutuję na ten temat w komentarzach.
Rzadko spotykany głos rozsądku. Ale fanatyków i tak nie przekona – oni będą stosować „czysty” MVVM i TDD, nawet jeśli wydłuży to czas wykonania projektu o 300%…
Dzięki za komentarz :). Ostatnimi czasy hobbystycznie wracam do programowania na 8-bitach (ZX Spectrum) i dochodzę do wniosku, że zbudowaliśmy potworną wieżę babel wokół projektowania software-u i samego programowania. Oczywiście bezspornie systemy są teraz daleko bardziej skomplikowane niż wtedy, ale coraz częściej wydaje mi się, że kładziemy większy nacisk na wszystko co do okoła a nie na sam kod a ludzie pasjonują się nie samym programowaniem ale całą tą sztucznie wydmuchaną otoczką. Z drugiej strony, całkiem często zdarza mi się wprowadzać poprawki lub modyfikacje w już istniejącym kodzie i często jak otworzę projekt po raz pierwszy to ręce opadają …. i zaczynam się zastanawiać czemu to wszystko służy. Żeby nie było – nie mam nic przeciwko MVVM i TDD czy DDD, ale to ma służyć czemuś konkretnemu, a nie być samym dla siebie w imię tego, że jest modne.
Ha, ciekaw jestem czy wspólna przeszłość implikuje podobne postrzeganie świata?
https://tinyurl.com/tomekzxspec 🙂
Kto wie, kto wie 🙂
„nie mamy już mieszanki kodu obsługującego akcje GUI z kodem realizującym rzeczywistą logikę.”
To można rozdzielić, tylko trzeba chcieć. Sam sie zastanawiam na WPF, ale odpycha mnie ta pisanina, model view, jakieś relay command itp. Framework, który, trzeba uzupełniać innymi bibliotekami jest dla mnie nieprzydatny. Do tego Microsoft sam ma w nosie swoje technologie, silverlight dead, Windows na terminale – dead. UWP – po co?. Znakomita część windows to i tak stare technologie, a windows phone jest martwy. Sorry, ale technologie microsoft to szajs (stabilny,ale szajs), ta firma dalej ma problem z dobrym wyswietlaniem czcionek, o skalowaniu juz nie mowiac. Sam proponuje nowe, nieprzetestowane technologie, a sam z nich nie korzysta (pije do office).
Programowanie powinno byc proste i przyjemne a nie płodzenie klas na potęgę, bo widok, bo coś.
Częściowo się zgodzę, chociaż nie do końca. Dzięki zastosowaniu MVVM łatwiej jest np. napisać testy do dobrze odseparowanej logiki a tych dodatkowych klas wcale tak dużo nie powstaje. Czytelność i testowalność kodu ma znaczenie, a nie ilość utworzonych klas. Ja lubię XAML-a jako takiego. Zdecydowanie wygodniej jest mi tworzyć interfejs z kodu niż klikać i przesuwać myszką po ekranie. Przy odrobinie praktyki w XAML-u robi się to po prostu szybciej. MVVM i XAML to też nie tylko WPF, martwy Silverlight czy średnio potrzebne UWP. To także Xamarin Forms oraz Platform Uno (chociaż jak się ten projekt rozwinie to czas pokaże).
A co do tego, że programowanie powinno być proste i przyjemne – to pełna zgoda. Dla mnie najprzyjemniejsze było w czasach ZX Spectrum albo DOS-a. Cały naddatek, który powstał później to jedna wielka masakra. Pamiętam pierwszą aplikację pisaną w Pascal for Windows z wykorzystaniem WinAPI – to była dopiero porażka. To wszystko i tak nic w porównaniu z bagnem jakie jest w przypadku aplikacji webowych. Ilość różnych frameworków i innych dziwnych wynalazków powstających w postępie geometrycznym jest przytłaczająca. Niestety programiści w dużej mierze sami zgotowali sobie ten los używając tego wszystkiego produkcyjnie – a teraz trzeba jakoś w tym szambie pływać, żeby nie utonąć.
Właśnie oglądam na pluralsight winforms best practices i tam podano jak odseparować logikę od wyglądu i wprowadzić testowalność, tak przybywa tam interfejsów, coś za coś, ale jak wychodzi to samo, to po co mam sie uczyc WPF?. Platform uno jest lub będzie płatne, więc odpada, równie dobrze można płacić za QT, które jest dojrzałe i przenośne, a nie trzeba wywalac kasy na visual studio. Xamarin Form – ok, ale jak ktos dziala na desktopie to zostaje tylko windows, bo WPF i WinForms nie przeniosa na maca i linuxa (nie maja w tym interesu)
Duzym plusem WinForms jest natywny wygląd, a uzytkownikom biznesowym zmiana wygladu i przyzwyczajen to ostatnia rzecz, ktorej potrzebuja. Powiem szczerze, nie widzialem duzej, solidnej aplikacji napisanej w WPF (tak, wiem VisualStudio, ale to oni cyzelują od lat i tak nie wykorzystuja potencjalu WPF).
„a teraz trzeba jakoś w tym szambie pływać, żeby nie utonąć.” dlatego jak wybieram ostrożnie, w pracy przed WPF bronie sie nogami, rekoma,myszką i krzesłem, abym nie musiał w tym pisać, bo skoro nie zawojowało świata przez 10 lat, to psu na bude.
Żeby było śmieszniej – fajna apka Visual Studio Code, która śmiga, ma fajne dodatki i jest naprawdę przenośna i szybka i co najwazniejsze – wygodna (CTRL-(SHIFT)-P), została napisana przez team z Microsoft i współpracowników w… frameworku javascript na silniku konkurencji :-D. Normalnie jaja.
W dodatku C# jest za bardzo rozgadany i zbyt wolno sie rozwija. Typ referencyjny non-nullable (nowosc w c# 8) powinien byc od samego poczatku, tak samo klasy proste (nowosc c# 8), a microsoft ciagle udziwnia zamiast poprawic implementacje (dlatego wprowadzono valuetask, typowe podejscie dla MS – dopiszemy klocuszka, co tam szkodzi jeszcze jeden).
Dla mnie jest żenujące, że firma, która zatrudnia coś ok. 100 tys. pracowników nie jest w stanie uporządkować interfejsu w Windows 10, poprawić skalowania (wywaliłem kasę na monitor 4k, na szczescie tylko 1kzł), czy poprawić jakość tekstu (w UWP jest slabo). Troche jestem za stary na bycie krolikiem doswiadczalnym.
Osobiście też uważam, ze cos poszlo nie tak z programowaniem, ale to moze tez kwestia doswiadczenia i wieku.
Całkiem fajna dyskusja z tego wyszła :). Żeby nie było – ja nie mam nic przeciwko Windows Forms, sam czasem używam a kiedyś używałem wyłącznie. Zdaję sobie też sprawę, że jest znacznie popularniejszy po dzień dzisiejszy jeżeli chodzi o klasyczny Windowsowy desktop. WPF daje mi po prostu więcej luzu a ze względu na charakter softu jaki najczęściej piszę (związane z wiuzalizacją i sterowaniem procesami technologicznymi – często na ekranach dotykowych) dużo łatwiej mi tu dopasować wszystko, zrobić animowane elementy itp. i nie potrzebuję do tego specjalnych kontrolek DevExpress-a czy Telerika. Używam tego od dawna i znam dobrze. Nie ma natomiast żadnego ciśnienia, żeby używać WPF przy klasycznych okienkowych aplikacjach – technologię dobieramy przecież do potrzeb projektu. WPF natomiast bardzo szybko pozwolił mi się wdrożyć w Xamarin Forms – co prawda XAML troszeczkę inny ale generalnie bardzo szybko można go do pewnego stopnia opanować mając wcześniejsze doświadczenie z WPF.
Visual Studio Code jest świetne, ale nie jestem fanem pisania wszystkiego co się da w Javascript. Ten język miał swoje pierwotne przeznaczenie i tam powinien był zostać. Electrona uważam za dziwnego potworka.
QT też jest spoko, pobawiłem się nim trochę, ale IMO jest zdecydowanie za drogie w wersji komercyjnej.
Co do C# to nie do końca się zgodzę, że rozwija się zbyt wolno – natomiast zgodzę się, że nie do końca w dobrym kierunku.
Cóż … to chyba tak jest, że na pewnym poziomie doświadczenia (a być może też i wieku) przestajemy się fascynować coraz to nowszymi wynalazkami a używamy po prostu tego co pozwala nam sprawnie zrobić robotę – dopóki na to pozwala.
A tak BTW to możesz wkleić link do tego kursu o którym piszesz ? Sam zerknę z ciekawości.
Hehe właśnie dlatego wylądowałem w Visual Studio, bo QT i Borland był za drogi, a ja chciałem kupić IDE, poza tym było, że w komplecie jest Visual Studio 6, ale to była ściema.
„ale nie jestem fanem pisania wszystkiego co się da w Javascript.” ja też nie, ale pewne cechy bym przeniósł do C#, np. składanie obiektów (używane mocno w React przy stanie) czy dekonstrukcję.
WPF i wizualizacja w przemysłówce – tak, tam to ma sens. U mnie jest cześć serwerowa lub typowa biznesówka dla biurowych, więc WPF tam nie widzę.
https://app.pluralsight.com/player?name=windows-forms-best-practices-m1&clip=0&course=windows-forms-best-practices&author=mark-heath
i jeszcze proponują: pluralsight.com/courses/patterns-library
Dzięki za linki. Oglądnę w wolnej chwili.
Pozdrawiam 🙂