Ako zvoliť vhodnú architektúru iOS (časť 2)

MVC, MVP, MVVM, VIPER alebo VIP

Časť 1 si môžete prečítať tu.

Hlavné architektúry iOS

Stručný prehľad.

MVC

Vrstvy MVC sú nasledujúce:

M: obchodná logika, sieťová vrstva a dátová vrstva

V: UI Layer (UIKit veci, Storyboardy, Xibs)

C: koordinuje sprostredkovanie medzi modelom a zobrazením.

Aby sme pochopili MVC, musíme pochopiť kontext, v ktorom bol vynájdený. MVC bol vynájdený v starých dňoch vývoja webových aplikácií, kde služba Views nemá stav. V starých časoch vždy, keď potrebujeme vizuálnu zmenu na webe, prehliadač znova načíta celý HTML znova. V tom čase neexistoval koncept zachovania a zachovania stavu pohľadu.

Existovali napríklad niektorí vývojári, ktorí sa zmiešali v rámci toho istého súboru HTML, PHP a prístupu k databáze. Hlavnou motiváciou MVC bolo teda oddelenie vrstvy pohľadu od vrstvy modelu. To zvýšilo testovateľnosť vrstvy modelu. Údajne v MVC by vrstva Zobraziť a Model nemala o sebe vedieť nič. Aby to bolo možné, bola vynájdená medzivrstva s názvom Controller. Bol použitý SRP.

Príklad cyklu MVC:

  1. Vyvolá sa užívateľská akcia / udalosť v zobrazovacej vrstve (napr. Obnovovacia akcia) a táto akcia sa oznámi Controlleru.
  2. Ovládač, ktorý žiada údaje do vrstvy modelu
  3. Modelovanie vrátených údajov do kontroléra
  4. Ovládač hovorí, že v prípade zobrazenia aktualizoval svoj stav novými údajmi
  5. Zobraziť aktualizovať jeho stav

Apple MVC

V systéme iOS je ovládač zobrazenia spojený s UIKitom a životným cyklom, takže to nie je iba MVC. V definícii MVC však nemožno povedať, že radič nemôže poznať implementáciu špecifickú pre pohľad alebo model. Jeho hlavným cieľom je oddeliť zodpovednosť za vrstvu Model od vrstvy Zobraziť, aby sme ju mohli znovu použiť a izolovať testovanie vrstvy Model.

ViewController obsahuje pohľad a vlastní model. Problém je, že sme v ViewController napísali kód kontroléra aj kód zobrazenia.

MVC často vytvára problém nazývaný Massive View Controller, ale stáva sa to len v aplikáciách s dostatočnou komplexnosťou.

Existuje niekoľko metód, ktoré môže vývojár použiť na zvýšenie spravovateľnosti ovládača zobrazenia. Niekoľko príkladov:

  • Extrahovanie logiky VC pre iné triedy, ako je zdroj údajov metód zobrazenia tabuľky a delegovanie pre iné súbory pomocou vzorového vzoru delegáta.
  • Vytvorte zreteľnejšie oddelenie zodpovednosti so zložením (napr. Rozdelenie VC na radiče zobrazenia dieťaťa).
  • Použite návrhový vzor koordinátora na odstránenie zodpovednosti za implementáciu navigačnej logiky vo VC
  • Použite triedu wrapperov DataPresenter, ktorá zapuzdruje logiku a transformuje dátový model na dátový výstup predstavujúci údaje predložené koncovému užívateľovi.

MVC verzus MVP

Ako vidíte diagram MVP, je veľmi podobný MVC

MVC bol krokom vpred, ale stále sa vyznačoval neprítomnosťou alebo mlčaním o niektorých veciach.

Medzitým sa World Wide Web rozrástol a vyvinulo sa mnoho vecí v komunite vývojárov. Napríklad programátori začali používať Ajax a načítavali iba časti stránok namiesto celej stránky HTML naraz.

V MVC si nemyslím, že by nič naznačovalo, že kontrolór by nemal poznať konkrétnu implementáciu View (absencia).

HTML bolo súčasťou vrstvy Zobraziť a veľa prípadov bolo hlúpe ako súložiť. V niektorých prípadoch prijíma iba udalosti od používateľa a zobrazuje vizuálny obsah GUI.

Keď sa časti webových stránok začali načítavať do častí, viedla táto segmentácia k zachovaniu stavu Zobraziť a k väčšej potrebe oddelenia zodpovednosti za prezentačnú logiku.

Prezentačná logika je logika, ktorá riadi, ako sa má UI zobrazovať a ako prvky UI spolu interagujú. Príkladom je riadiaca logika toho, kedy by sa mal indikátor zavádzania začať zobrazovať / animovať a kedy by sa mal prestať zobrazovať / animovať.

V MVP a MVVM by vrstva pohľadu mala byť hlúpa ako sakra bez akejkoľvek logiky alebo inteligencie v nej a v systéme iOS by ovládač zobrazenia mal byť súčasťou vrstvy vrstvy. Skutočnosť, že pohľad je nemý, znamená, že aj prezentačná logika zostane mimo vrstvy zobrazenia.

Jedným z problémov MVC je to, že nie je jasné, kde by mala zostať prezentačná logika. O tom jednoducho mlčí. Mala by byť logika prezentácie vo vrstve Zobraziť alebo vo vrstve modelu?

Ak je úlohou modelu iba poskytovať „prvotné“ údaje, znamená to, že kód v zobrazení by bol:

Zoberme si nasledujúci príklad: máme používateľa s menom a priezviskom. V zobrazení musíme meno používateľa zobraziť ako „Priezvisko, Krstné meno“ (napr. „Flores, Tiago“).

Ak je úlohou modelu poskytovať „prvotné“ údaje, znamená to, že kód v zobrazení by bol:

let firstName = userModel.getFirstName ()
let lastName = userModel.getLastName ()
nameLabel.text = priezvisko + „,“ + meno

To znamená, že za spracovanie logiky používateľského rozhrania bude zodpovedať pohľad. To však znemožňuje logiku používateľského rozhrania testovať jednotku.

Druhým prístupom je vystavenie modelu iba údajom, ktoré je potrebné zobraziť, a skryť akúkoľvek obchodnú logiku z pohľadu. Nakoniec však skončíme s modelmi, ktoré zvládajú logiku podnikania aj rozhrania UI. Bolo by to testovateľné na jednotku, ale potom Model skončí, implicitne je závislý od Pohľadu.

let name = userModel.getDisplayName ()
nameLabel.text = name

MVP je o tom jasná a logika prezentácie zostáva vo vrstve Presenter Layer. To zvyšuje testovateľnosť vrstvy Presenter. Teraz je možné vrstvu Model a Presenter Layer ľahko testovať.

Zvyčajne v implementáciách MVP je pohľad skrytý za rozhraním / protokolom a v prezentujúcom by nemali byť žiadne odkazy na UIKit.

Ďalšou vecou, ​​ktorú treba mať na pamäti, sú prechodné závislosti.

Ak má kontrolór vrstvu Business Business Layer ako závislosť a Business Layer má vrstvu Data Access Layer ako závislosť, potom má kontrolór prechodnú závislosť vrstvy Data Access Layer. Keďže implementácie MVP bežne používajú zmluvu (protokol) medzi všetkými vrstvami, nemá prechodné závislosti.

Rôzne vrstvy sa tiež menia z rôznych dôvodov a rôznymi rýchlosťami. Takže keď zmeníte vrstvu, nechcete, aby to spôsobovalo sekundárne efekty / problémy v ostatných vrstvách.

Protokoly sú stabilnejšie ako triedy. Protokoly neobsahujú podrobnosti o implementácii a so zmluvami, takže je možné zmeniť podrobnosti o implementácii vrstvy bez ovplyvnenia ostatných vrstiev.

Zmluvy (protokoly) tak vytvárajú oddelenie medzi vrstvami.

MVP vs MVVM

Schéma MVVM

Jedným z hlavných rozdielov medzi MVP a MVVM je to, že v MVP Presenter komunikuje s rozhraním Zobraziť prostredníctvom rozhraní a v MVVM je Pohľad orientovaný na zmeny dát a udalostí.

V MVP vytvárame manuálne väzby medzi Presenter a View pomocou rozhraní / protokolov.
V MVVM robíme automatické viazanie údajov pomocou niečoho ako RxSwift, KVO alebo používame mechanizmus s generikami a uzávermi.

V MVVM nepotrebujeme ani zmluvu (napr. Java rozhranie / protokol iOS) medzi ViewModel a View, pretože zvyčajne komunikujeme prostredníctvom vzorového vzoru pozorovateľa.

MVP používa model delegovania, pretože vrstva Presenter Layer deleguje objednávky do vrstvy View, takže potrebuje niečo vedieť o zobrazení, aj keď ide iba o podpis rozhrania / protokolu. Pomysli na rozdiel medzi Centrom notifikácie a delegátmi TableView. Centrum upozornení nepotrebuje rozhrania na vytvorenie komunikačného kanála, ale delegáti TableView používajú protokol, ktorý by triedy mali implementovať.

Pomyslite na prezentačnú logiku indikátora načítania. V MVP robí moderátor ViewProtocol.showLoadingIndicator. V MVVM môže byť v ViewModel vlastnosť isLoading. Vrstva Zobraziť prostredníctvom automatickej väzby údajov zistí, kedy sa táto vlastnosť zmení a obnoví sa. MVP je nevyhnutnejšia ako MVVM, pretože moderátorka dáva rozkazy.

MVVM sa týka skôr zmien údajov ako priamych objednávok a medzi zmenami údajov a aktualizáciami zobrazení robíme asociácie. Ak použijeme RxSwift a funkčné reaktívne programovacie paradigma spolu s MVVM, urobili sme kód ešte menej nevyhnutným a deklaratívnejším.

Testovanie MVVM je jednoduchšie ako testovanie MVP, pretože MVVM používa návrhový vzorec pozorovateľa, ktorý prenáša údaje medzi komponentmi oddelene.
Takže môžeme testovať len pozeraním na zmeny v údajoch len porovnaním týchto dvoch objektov a nie vytváraním falošných metód, ktoré metódy volajú na testovanie komunikácie medzi prehliadačom a prezentujúcim.

PS: Urobil som niekoľko aktualizácií článku, ktorý spôsobil, že to veľmi rástlo, takže bolo potrebné ho rozdeliť na tri časti. Tu si môžete prečítať tretiu časť.

Druhá časť tu končí. Akákoľvek spätná väzba je vítaná. Tretia časť bude hovoriť o VIPER, VIP, reaktívnom programovaní, kompromisoch, obmedzeniach a kontexte.

Ďakujem za čítanie! Ak sa vám tento článok páčil, tlieskajte
aby ju mohli prečítať aj iní ľudia :)