ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 150
Numărul 149 Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 14
Abonament PDF

Design pattern-ul MVVM

Andrei Moldovan
Software Developer
@Business Logic Systems Ltd.



DIVERSE


Orice programator încearcă să fie cât mai ordonat atunci când scrie cod. Fiecare echipă își organizează proiectul în așa fel încât acesta să fie cât mai ușor de întreținut și să poată fi înțeles cu ușurință de membrii noi ai echipei. Această practică poate fi datorată și folosirii design pattern-urilor. Știm că există numeroase astfel de reguli de organizare a codului și că odată aleasă una dintre ele, este greu și costisitor ca aceasta să fie schimbată. Totuși este important ca programatorii să fie la curent cu noile design pattern-uri pentru a putea profita la maxim de avantajele oferite de acestea.

Model-View-Viewmodel (MVVM) este un design pattern folosit în ingineria software care a fost introdus prima oară de către Microsoft ca o metodă de particularizare a modelului de prezentare introdus de Martin Fowler. De fapt se pare că Microsoft folosea MVVM pentru proiectele dezvoltate intern, precum Microsoft Expression Blend, pe când nucleul platformei WPF era în construcție. Bazat în mare parte pe modelul Model-View-Controller (MVC), acesta se adresează în special dezvoltării interfeței cu utilizatorii a platformelor moderne ((HTML5, Windows Presentation Foundation, - WPF, și Silverlight), acolo unde există un dezvoltator orientat special spre acest lucru, având sarcini diferite de ale unui dezvoltator obișnuit care se ocupă în general de logica business și de dezvoltarea interacțiunii cu serverul.

Ca structură, acesta este alcatuit din trei părți esențiale ce pot fi deduse și din denumirea design pattern-ului: un Model, un View și un ViewModel. Această structură seamană cu cea a MVC-ului, dar oferă în plus ușurința utilizării XAML-ului și a Windows Presentation Foundation, prin cuplarea datelor cât mai aproape de Model folosind XAML, View Model și orice verificare de date a nivelului Business pentru a valida datele înaintea afișării acestora pe interfață. Modelul se referă la datele efectiv cu care se lucrează dar și la nivelul de acces la aceste date. Spre exemplu într-un model ar putea fi accesate obiecte care citesc din baza de date informații legate de o anumită persoană. View-urile, la fel ca și în cazul clasic se referă la partea vizuală care va fi afișată pe interfața grafică, cum ar fi butoanele, ferestrele, graficele și alte controale. Acestea nu conțin partea de logică business. Marele avantaj în acest caz este că un designer poate să se ocupe de partea grafică a aplicației lucrând doar cu view-ul, în timp ce logica din spate rămâne neafectată. ViewModel-urile reprezintă niște modele pentru view-uri, mai precis acestea se referă la o abstractizare a view-urilor care servesc și la binding-ul datelor între view și model. Pot fi privite și ca niște aspecte specializate ale Controalelor din design pattern-ul MVC (care acționează ca și data bindgins sau converters) în așa fel încât să schimbe informația din formatul modelului în formatul view-ului și să paseze comenzi din view în model. ViewModel-urile expun proprietățile publice, comenzile și abstractizările și au fost asemănate cu o stare conceptuală a datelor, spre depsebire de starea reală a datelor din model. Există discuții în ceea ce privește clasa din spatele view-ului. Majoritatea specialiștilor susțin că aceasta ar trebui să conțină doar metoda InitializeComponent() în cazul WPF și Silverlight, însă în anumite cazuri nu se merită mutarea unor metode în viewmodel.

View-ul comunică doar cu ViewModel-ul, în timp ce ViewModel-ul este privit ca un punct intermediar între View și Model. De asemenea, Modelul este singurul care interacționează cu baza de date. Acest model are sens în practică doar dacă se folosește în combinație cu o bază de date. În caz contrar obiectele de date precum entitățile din EDMX și Linq nu au logică în acest context. O diagramă a acestui design pattern poate fi observată și in figura de mai jos.

Alte două funcționalități care fac ca acesta să fie atât de des folosit sunt data template-urile și resursele de sistem. Template-urile aplică View-uri asupra obiectelor unui ViewModel. Programatorii pot să le declare în XAML și să lase resursele de sistem să localizeze în mod automat iar apoi să aplice acele template-uri la runtime.

Întrucât aceast design pattern poate fi destul de greu de implementat, au fost create câteva platforme care să ajute programatorii în implementarea lui cum ar fi MVVM Light sau Caliburn. Personal îl recomand pe cel din urmă deoarece oferă avantajul recunoașterii automate a view-ului de către viewmodel, nemaifiind necesară crearea unei clase ajutătoare care să facă acest lucru.

Să luăm un exemplu simplu cu o aplicație care afișează dintr-o bază de date informații despre produse : nume, preț unitar și id. În model va trebui să avem partea de accesare a datelor. Modul în care acestea vor fi accesate rămâne la latitudinea programatorului. Această clasă va implementa INotifyPropertyChanged și va conține cele 3 proprietăți, fiecare având pe setter OnPropertyChanged("Proprietate") pentru a semnaliza modificarea valorii proprietății. Trebuie acordată atenție în mod special numelui proprietății deoarece acesta se transmite ca și string.

ViewModel-ul va conține toată partea de care are nevoie utilizatorul pentru a interacționa cu aplicația. Aici se pot pune sortările, ștergerile din listă sau orice alte operațiuni necesare. În cazul de față doar 2 comenzi, GetProduct și SaveProduct ce vor fi folosite pentru a aduce un obiect din model în viewmodel și pentru a salva un produs. Acestea sunt de tipul ICommand și au o sintaxă de tipul :

public ICommand SaveProductCommand{
get{
if (_saveProductCommand == null) {
_saveProductCommand = new RelayCommand(param => SaveProduct(),
             param => (CurrentProduct != null)); }

  return _saveProductCommand;
  }
}

Tot aici apare și clasa RelayCommand, esențială pentru ca MVVM să funcționeze. Aceasta conține o comandă ce va fi executată de alte clase pentru a rula cod în clasa de bază prin invocarea de delegates.

View-ul este partea care definește modul în care va arăta aplicația. De asemenea se vor defini două DataTemplate-uri, unul pentru model și unul pentru viewmodel.

Pentru a porni aplicația mai trebuie adăugate următoarele linii de cod în App.xaml.cs, care crează ViewModel-ul și asociază datacontext-ul ferestrei în viewmodel:

MainWindow app = new MainWindow();
ProductViewModel viewModel = new ProductViewModel();
app.DataContext = viewModel;
app.Show();

Și totuși când ar trebui să folosim acest model? Deși structura lui este una logică și oferă organizare în cod, acesta nu se pretează pentru orice fel de proiect. Dacă avem de-a face cu un proiect unde nu există o interfață grafică prea complexă nu se prea justifică folosirea MVVM, codul putând fi scris chiar și în code behind. De asemenea unii programatori nu recomandă folosirea acestui pattern dacă nu se dorește realizarea de unit-teste. Întrucât ușurința în scrierea testelor este unul din avantajele acestuia, este de preferat ca acesta să fie folosit doar împreună cu acestea. Este total neproductivă și deci nu este recomandată folosirea unui design pattern într-o aplicație simplă "Hello World!". Orice dezvoltator software poate să înțeleagă câteva linii de cod , chiar și dacă sunt scrise dezorganizat. Totuși, pe măsură ce numărul de linii de cod dintr-un program crește, crește și numărul funcționalităților.

Pe lângă dezavantajele amintite mai sus, ar mai fi și faptul că în unele cazuri poate fi dificilă proiectarea viewmodel-ului în așa fel încât să se obțină gradul de generalitate dorit și de asemenea debug-ul pentru data binding este mai greu de realizat față de metodele clasice care foloseau code behind.

În concluzie MVVM oferă anumite avantaje precum separarea view-ului de logica business și ușurința în scrierea testelor unitare, însă programatorii trebuie să fie atenți dacă acest design pattern se pretează sau nu pentru proiectul lor.

NUMĂRUL 149 - Development with AI

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects