Puneți controlerul de vizualizare pe o dietă cu dezvoltarea site-ului web de cod MVVM, jocuri pe computer

- Distribuiți pe Facebook
- Tweet
- Distribuiți pe Google+
- Postați pe Tumblr
- Fixează-l
- Adăugați la Pocket
- Trimite email
În ultima mea postare din această serie, am scris despre modelul Model-View-Controller și despre unele dintre imperfecțiunile sale. În ciuda avantajelor clare pe care MVC le aduce dezvoltării software-ului, acesta nu ajunge la aplicațiile mari sau complexe Cocoa.
Cu toate acestea, aceasta nu este o veste. De-a lungul anilor, au apărut mai multe modele arhitecturale care vizează defectele modelului Model-View-Controller. Poate ai auzit despre asta MVP, Model-Vizualizare-Prezentator și MVVM, De exemplu Model-View-ViewModel. Aceste tipare arată și se simt similare cu modelul Model-View-Controller, dar abordează și unele dintre problemele pe care modelul Model-View-Controller le prezintă.
1. De ce Model-Vizualizare-VizualizareModel
Foloseam modelul Model-View-Controller de ani de zile înainte să întâlnesc accidental modelul Model-Vizualizare-VizualizareModel Șablon. Nu este surprinzător faptul că MVVM este un descendent al comunității Cocoa, dat fiind că originile sale se întorc la Microsoft. Cu toate acestea, modelul MVVM a fost portat la Cocoa și adaptat la cerințele și nevoile schelelor Cocoa și a câștigat recent o importanță în comunitatea Cocoa.
Cel mai atractiv este modul în care MVVM se simte ca o versiune actualizată a modelului Model-View-Controller. Aceasta înseamnă că nu necesită o schimbare dramatică a mentalității. Odată ce ați înțeles elementele de bază ale modelului, este destul de ușor de implementat, nu mai dificil decât modelul model-vizualizare-controler.
2. Puneți View Controller pe o dietă
În postarea anterioară am scris că controlerele dintr-o aplicație tipică Cocoa sunt puțin diferite de controlerele definite de Reenskaug în modelul original MVC. De exemplu, pe iOS, un controler de vizualizare controlează o vizualizare. Responsabilitatea dvs. exclusivă este de a completa vizualizarea pe care o gestionează și de a răspunde la interacțiunea utilizatorului. Cu toate acestea, aceasta nu este singura sarcină a View Controllers în majoritatea aplicațiilor iOS?
Modelul MVVM introduce o a patra componentă în mix, Arată modelul, ceea ce ajută la reorientarea controlerului de vizualizare. Acest lucru se face prin asumarea unora dintre responsabilitățile controlerului de vizualizare. Aruncați o privire la următoarea diagramă pentru a înțelege mai bine modul în care modelul View se încadrează în modelul Model-View-ViewModel.

După cum arată diagrama, controlerul de vizualizare nu mai deține modelul. Modelul de vizualizare deține modelul, iar controlerul de vizualizare solicită modelului de vizualizare datele care trebuie afișate.
Aceasta este o diferență importantă față de modelul model-vizualizare-controler. Controlerul de vizualizare nu are acces direct la model. Modelul de vizualizare oferă controlerului de vizualizare datele pe care trebuie să le afișeze în vizualizarea sa.
Relația dintre View Controller și viziunea sa rămâne neschimbată. Acest lucru este important deoarece controlerul de vizualizare se poate concentra pe completarea vizualizării sale și gestionarea interacțiunii utilizatorului. Pentru aceasta a fost dezvoltat View Controller.
Rezultatul este destul de dramatic. Controlerul de vizualizare este supus unei diete și multe responsabilități sunt transferate la modelul de vizualizare. În cele din urmă, nu mai există un controler de vizualizare care acoperă sute sau chiar mii de linii de cod.
3. Responsabilitățile modelului vizual
Probabil vă întrebați cum se încadrează modelul de vizualizare în imaginea de ansamblu. Care sunt sarcinile modelului vizual? Cum este relația cu controlerul de vizualizare? Și ce zici de model?
Diagrama pe care v-am arătat-o mai devreme ne oferă câteva indicii. Să începem cu modelul. Modelul nu mai aparține View Controller. Modelul de vizualizare deține modelul și acționează ca un proxy pentru controlerul de vizualizare. Când controlerul de vizualizare are nevoie de un element de date din modelul său de vizualizare, acesta îi cere modelului datele brute și îl formatează astfel încât controlerul de vizualizare să îl poată utiliza imediat în vizualizarea sa. Controlorul de vizualizare nu este responsabil pentru manipularea și formatarea datelor.
Diagrama arată, de asemenea, că modelul este deținut de modelul de vizualizare, nu de controlerul de vizualizare. De asemenea, trebuie remarcat faptul că modelul Model-View-ViewModel ia în considerare relația strânsă dintre controlerul de vizualizare și vizualizarea acestuia, care este caracteristic aplicațiilor Cocoa. Din acest motiv, MVVM se simte ca o alegere naturală pentru aplicațiile de cacao.
4. Un exemplu
Deoarece modelul Model-View-ViewModel nu este inclus în Cocoa, nu există reguli stricte pentru implementarea modelului. Din păcate, acest lucru devine confuz de mulți dezvoltatori. Pentru a clarifica câteva lucruri, vreau să vă arăt un exemplu de bază al unei aplicații care utilizează modelul MVVM. Creăm o aplicație foarte simplă care extrage datele meteo pentru o locație predefinită din API-ul Dark Sky și arată utilizatorului temperatura actuală.
Pasul 1: configurarea proiectului
Porniți Xcode și creați un nou proiect bazat pe Aplicație cu vizualizare unică Șablon. Folosesc Xcode 8 și Swift 3 pentru acest tutorial.

Denumiți proiectul MVVM, si pune limba la Rapid și Dispozitive la iPhone.

Pasul 2: creați un model de vizualizare
Într-o aplicație tipică Cocoa care rulează modelul Model-View-Controller, View Controller va face cererea de rețea. Puteți utiliza un manager pentru a face cererea de rețea, dar controlerul de vizualizare ar ști în continuare de unde provin datele meteo. Mai important, primește datele brute și trebuie să le formateze înainte de a fi afișate utilizatorului. Aceasta nu este abordarea pe care o folosim atunci când adoptăm modelul Model-View-ViewModel.
Să creăm un model de vizualizare. Creați un nou fișier Swift, denumiți-l WeatherViewViewModel.swift, și definiți o clasă numită WeatherViewViewModel .

Ideea este simplă. Controlerul de vizualizare solicită modelului de vizualizare temperatura actuală pentru o locație predefinită. Deoarece modelul de vizualizare trimite o cerere de rețea către API-ul Dark Sky, metoda acceptă o blocare care este apelată atunci când modelul de vizualizare are date pentru controlerul de vizualizare. Aceste date pot fi temperatura actuală, dar pot fi și un mesaj de eroare. Așa arată metoda StromTemperatur (completare:) В a modelului de vizualizare. Vom completa detalii în câteva momente.
Declarăm un alias de tip și definim o metodă, StromTemperature (Completion:), care acceptă o închidere a tipului CurrentTemperatureCompletion .В
Nu este dificil de implementat dacă sunteți familiarizat cu rețeaua și API-ul URLSession. Aruncați o privire la codul de mai jos și observați că am folosit un API enumerat pentru a păstra totul frumos și curat.
Singura bucată de cod pe care nu v-am arătat-o încă este implementarea metodei de temperatură (prin:). În această metodă extragem temperatura curentă din răspunsul Cerului Întunecat.
Într-o aplicație de producție, aș alege o soluție mai robustă pentru a analiza răspunsul, de ex. B. ObjectMapper sau Unbox.
Pasul 3: Integrarea modelului de vizualizare
Acum putem folosi modelul de vizualizare în controlerul de vizualizare. Creăm o proprietate pentru modelul de vizualizare și definim, de asemenea, trei ieșiri pentru interfața cu utilizatorul.
Rețineți că controlerul de vizualizare deține modelul de vizualizare. În acest exemplu, controlerul de vizualizare este, de asemenea, responsabil pentru instanțierea modelului său de vizualizare. În general, prefer să injectez modelul de vizualizare în controlerul de vizualizare, dar hai să o facem deocamdată.
În vizualizarea Controller viewDidLoad () metoda numim o metodă de ajutor, fetchWeatherData () .
În fetchWeatherData (), întrebăm modelul de vizualizare despre temperatura curentă. Înainte de a interoga temperatura, ascundem eticheta și butonul și afișăm indicatorul de activitate. În închidere trecem la fetchWeatherData (Finalizare:), Actualizăm interfața utilizatorului completând eticheta de temperatură și ascunzând indicatorul de activitate.
Butonul este asociat cu o acțiune, fetchWeatherData (_:), în care numim și metoda helper fetchWeatherData (). După cum puteți vedea, metoda de ajutor ne ajută să evităm duplicarea codului.
Pasul 4: creați interfața cu utilizatorul
Ultima piesă a puzzle-ului este crearea interfeței cu utilizatorul pentru aplicația mostră. Deschis Placă de bază și adăugați o etichetă și un buton la o vizualizare verticală a stivei. Un indicator de activitate este adăugat în partea de sus a vizualizării stivei, centrat vertical și orizontal.

Nu uitați să conectați ieșirile și acțiunea definită în clasa ViewController!
Acum construiți și lansați aplicația pentru a încerca. Amintiți-vă, aveți nevoie de o cheie API Dark Sky pentru ca aplicația să funcționeze. Vă puteți înscrie pentru un cont gratuit pe site-ul Dark Sky.
5. Care sunt beneficiile?
Deși am mutat doar câteva lucruri minore în modelul de vizualizare, este posibil să vă întrebați de ce este necesar acest lucru. Ce am câștigat? De ce ar trebui să adăugați acest strat suplimentar de complexitate?
Cel mai evident avantaj este că controlerul de vizualizare este mai subțire și mai concentrat pe gestionarea vederii sale. Aceasta este sarcina de bază a unui controler de vizualizare: gestionarea vizualizării sale.
Dar există un beneficiu mai subtil. Deoarece View Controller nu este responsabil pentru obținerea datelor meteo de la API-ul Dark Sky, nu cunoaște detaliile acestei sarcini. Datele meteo pot proveni de la un alt serviciu meteo sau dintr-un răspuns în cache. Controlerul de vizualizare nu ar fi și nu trebuie să știe.
De asemenea, testarea se îmbunătățește foarte mult. Se știe că controlerele de vizualizare sunt dificil de testat din cauza relației lor strânse cu planul de vizualizare. Mutând o parte din logica de afaceri în modelul de vizualizare, îmbunătățim imediat testabilitatea proiectului. Testarea modelelor de vizualizare este surprinzător de ușoară, deoarece nu au un link către nivelul de vizualizare al aplicației.
Concluzie
Modelul Model-View-ViewModel este un progres major în proiectarea aplicațiilor Cocoa. Controlerele de vizualizare nu sunt la fel de extinse, modelele de vizualizare sunt mai ușor de asamblat și testat și facilitează lucrul cu proiectul.
În această scurtă serie, am zgâriat doar suprafața. Există mult mai multe de scris despre modelul Model-View-ViewModel. A devenit unul dintre tiparele mele preferate de-a lungul anilor și de aceea vorbesc și scriu despre asta tot timpul. Încercați și spuneți-mi ce părere aveți!
Între timp, puteți consulta câteva dintre celelalte postări ale noastre despre dezvoltarea aplicațiilor Swift și iOS.