Kako izbrati ustrezno arhitekturo iOS (2. del)

MVC, MVP, MVVM, VIPER ali VIP

Prvi del se lahko posvetujete tukaj.

Glavne arhitekture iOS-a

Kratek pregled.

MVC

Plasti MVC so naslednje:

M: Poslovna logika, omrežni sloj in sloj dostopa do podatkov

V: Sloj UI (stvari UIKit, Storyboards, Xibs)

C: Koordinira posredovanje med modelom in pogledom.

Za razumevanje MVC moramo razumeti kontekst, v katerem je bil izumljen. MVC je bil izumljen v starih dneh spletnega razvoja, kjer Views nima stanja. V starih časih vsakič, ko potrebujemo vizualno spremembo na spletnem mestu, brskalnik znova naloži celoten HTML. Takrat še ni bilo mogoče ohraniti in shraniti pojma stanja pogleda.

Na primer, bilo je nekaj razvijalcev, ki so se mešali znotraj iste datoteke HTML, PHP in dostopa do baze podatkov. Glavna motivacija MVC-ja je bila torej ločitev View-ja od plasti Model. To je povečalo testnost plasti modela. Domnevno v MVC sloj Pogled in Model ne bi smel vedeti drug o drugem. Da bi bilo to mogoče, je bil izumljen vmesni sloj z imenom Controller. To je bila SRP, ki je bila uporabljena.

Primer cikla MVC:

  1. Uporabniško dejanje / dogodek v sloju pogleda (npr .: osveži dejanje) se sproži in to dejanje sporoči krmilniku
  2. Krmilnik, ki podatke pošlje v plast modela
  3. Modeliranje vrne podatke v Controller
  4. Controller pravi, da mora Pogled posodobiti njegovo stanje z novimi podatki
  5. Prikaži posodobitev njegovega stanja

Apple MVC

V iOS-u je nadzorni regulator povezan s sistemom UIKit in življenjskim ciklom, zato ni čisti MVC. Vendar pa v definiciji MVC ni ničesar, kar bi povedalo, da krmilnik ne more poznati specifične izvedbe pogleda ali modela. Njegov glavni namen je ločiti odgovornosti sloj modela od plasti View, tako da ga lahko ponovno uporabimo in preizkusimo plast modela osamljeno.

ViewController vsebuje Pogled in je lastnik modela. Težava je v tem, da smo v ViewController zapisali kodo regulatorja in kodo pogleda.

MVC pogosto ustvarja imenovano težavo Massive View Controller, vendar se to zgodi le in postane resna stvar v aplikacijah z dovolj zapletenostjo.

Obstaja nekaj načinov, ki jih lahko razvije za izboljšanje upravljivosti View Controllerja. Nekaj ​​primerov:

  • Ekstrahiranje logike VC za druge razrede, kot je tabelni prikaz metod podatkov, in delegat za druge datoteke s pomočjo delegatskega oblikovalskega vzorca.
  • Ustvari natančnejšo ločitev odgovornosti s sestavo (npr. Razdelite VC na krmilnike za prikaz otrok).
  • Z vzorcem zasnove koordinatorja odstranite odgovornost za izvajanje navigacijske logike v VC-ju
  • Uporabite razred ovoja DataPresenter, ki zajema logiko in pretvori podatkovni model v izhod podatkov, ki predstavlja podatke, predstavljene končnemu uporabniku.

MVC proti MVP

Kako vidite diagram MVP je zelo podoben MVC

MVC je bil korak naprej, vendar ga je še vedno zaznamovala odsotnost ali tišina o nekaterih stvareh.

Medtem je svetovni splet rastel in v skupnosti razvijalcev se je razvijalo veliko stvari. Na primer, programerji so začeli uporabljati Ajax in naenkrat nalagali le dele strani namesto celotne strani HTML.

V MVC-ju mislim, da nič ne kaže na to, da krmilnik ne bi smel poznati posebne izvedbe Pogled (odsotnost).

HTML je bil del sloja View in mnogi primeri so bili neumni. V nekaterih primerih od uporabnika prejema samo dogodke in prikaže vizualno vsebino GUI-ja.

Ker so se deli spletnih strani začeli nalagati na dele, je ta segmentacija vodila v smeri vzdrževanja stanja View in večje potrebe po ločitvi odgovornosti predstavitvene logike.

Logika predstavitve je logika, ki nadzoruje, kako naj se uporabniški vmesnik prikaže in kako elementi uporabniškega vmesnika medsebojno delujejo. Primer je krmilna logika, kdaj naj se kazalnik nalaganja začne prikazovati / animirati in kdaj naj preneha prikazovati / animirati.

V MVP in MVVM bi moral biti plast pogleda neumna, brez kakršne koli logike ali inteligence v njej, v iOS-u pa bi moral biti kontroler pogleda del razglednega sloja. Dejstvo, da je View neumen, pomeni, da celo predstavitvena logika ne ostane v sloju Pogled.

Eden od težav MVC je, da ni jasno, kje naj ostane logika predstavitve. O tem preprosto molči. Ali mora biti logika predstavitve v sloju Pogled ali v modelnem sloju?

Če je vloga modela zgolj posredovanje "surovih" podatkov, to pomeni, da bi bila koda v pogledu:

Razmislite o naslednjem primeru: imamo uporabnika z imenom in priimkom. V pogledu moramo uporabniško ime prikazati kot "Priimek, ime" (npr. "Flores, Tiago").

Če je vloga modela zagotoviti »surove« podatke, to pomeni, da bi bila koda v pogledu:

pusti firstName = userModel.getFirstName ()
naj lastName = userModel.getLastName ()
nameLabel.text = lastName + “,“ + firstName

Torej, to pomeni, da bi morala odgovornost odgovarjati na logiko uporabniškega vmesnika. Toda to onemogoča logiko uporabniškega vmesnika.

Drugi pristop je, da model izpostavi samo podatke, ki jih je treba prikazati, pri čemer skriva kakršno koli poslovno logiko pred pogledom. Toda na koncu zaključimo z modeli, ki upravljajo tako s poslovno kot z uporabniško uporabniško logiko. Bilo bi preizkusno, vendar potem model konča, implicitno odvisen od pogleda.

naj ime = userModel.getDisplayName ()
nameLabel.text = ime

MVP je v tem jasno in logika predstavitve ostaja v sloju predstaviteljev. S tem se poveča testnost plasti Presenter. Zdaj je model in sloj predstaviteljev lahko preizkušen.

Običajno je v izvedbah MVP pogled skrit za vmesnikom / protokolom in v predstavitelju ne sme biti nobenih sklicev na UIKit.

Upoštevati je treba tudi prehodne odvisnosti.

Če ima krmilnik poslovni sloj kot odvisnost in ima poslovni sloj kot odvisnost sloj dostopa do podatkov, potem ima regulator regulator prehodno odvisnost za nivo dostopa do podatkov. Ker izvedbe MVP običajno uporabljajo pogodbo (protokol) med vsemi sloji, ni prehodnih odvisnosti.

Tudi različni sloji se spreminjajo iz različnih razlogov in z različnimi stopnjami. Torej, ko spremenite sloj, ne želite, da to povzroči sekundarne učinke / težave v drugih slojih.

Protokoli so bolj stabilni kot razredi. V protokolih ni podrobnosti o izvajanju in s pogodbami, zato je mogoče spremeniti podrobnosti o izvedbi sloja, ne da bi to vplivalo na druge sloje.

Torej pogodbe (protokoli) ustvarjajo ločitev med plastmi.

MVP proti MVVM

MVVM diagram

Ena glavnih razlik med MVP in MVVM je, da v MVP predstavitelj komunicira s pogledom prek vmesnikov, v MVVM pa je pogled usmerjen v spremembe podatkov in dogodkov.

V MVP-ju naredimo ročno vezavo med Presenter in View z vmesniki / protokoli.
V MVVM naredimo samodejno zavezujoče podatke z uporabo nekaj podobnega kot RxSwift, KVO ali uporabimo mehanizem z generičnimi in zapornicami.

V MVVM sploh ne potrebujemo pogodbe (npr. Java vmesnik / iOS protokol) med ViewModel in View, ker običajno komuniciramo prek Observer Design Pattern.

MVP uporablja vzorec delegatov, ker predstavniki sloja predstaviteljev naročajo na razgledni sloj, zato mora nekaj vedeti o pogledu, tudi če gre le za podpis vmesnika / protokola. Pomislite na razliko med Notification Center in TableView Delegati. Center za obveščanje ne potrebuje vmesnikov, da ustvari komunikacijski kanal, vendar TableView Delegates uporablja protokol, ki bi ga morali izvajati razredi.

Pomislite na logiko predstavitve indikatorja nalaganja. V MVP-ju izvajalec ViewProtocol.showLoadingIndicator. V MVVM lahko v ViewModelu obstaja lastnost isLoading. Plast pogleda s pomočjo samodejne vezave podatkov zazna, kdaj se ta lastnost spremeni in osveži. MVP je bolj pomemben od MVVM, ker predstavitelj daje ukaze.

MVVM gre bolj za spremembe podatkov kot za neposredna naročila, med spremembami podatkov pa si ogledamo posodobitve. Če uporabljamo RxSwift in funkcionalno paradigmo reaktivnega programiranja skupaj z MVVM, smo kodo naredili še manj nujno in bolj deklarativno.

MVVM je lažje preizkusiti kot MVP, ker MVVM uporablja Observer Design Pattern, ki prenaša podatke med komponentami na nevezan način.
Tako lahko preizkusimo zgolj gledanje sprememb podatkov samo s primerjavo obeh predmetov, ne pa ustvarjanjem posmeha klicev metod za preverjanje komunikacije med View in Presenter.

PS: Naredil sem nekaj posodobitev članka, zaradi katerih je močno zrasel, zato ga je bilo treba razdeliti na tri dele. Tretji del si lahko preberete tukaj.

Drugi del se tu konča. Vse povratne informacije so dobrodošle. Tretji del bo govoril o VIPER-ju, VIP-u, reaktivnem programiranju, kompromisih, omejitvah in kontekstualnem smislu.

Hvala za branje! Če vam je bil ta članek všeč, ga zapišite
tako lahko tudi drugi preberejo :)