Kuidas valida sobivat iOS-i arhitektuuri (2. osa)

MVC, MVP, MVVM, VIPER või VIP

Esimese osaga saate tutvuda siin.

IOS-i peamised arhitektuurid

Lühike ülevaade.

MVC

MVC kihid on järgmised:

M: äriloogika, võrgukiht ja andmetele juurdepääsu kiht

V: UI kiht (UIKit asjad, süžeeskeemid, Xibid)

C: koordineerib mudeli ja vaate vahelist vahendamist.

MVC mõistmiseks peame mõistma konteksti, milles see leiutati. MVC leiutati vanadel veebiarenduspäevadel, kus Viewsil pole riiki. Kui vanasti on vaja veebisaidi visuaalset muutmist, laadib brauser uuesti kogu HTML-i. Sel ajal polnud kontseptsiooni vaate oleku säilitamisest ja salvestamisest.

Näiteks olid mõned arendajad, kes segasid sama HTML-faili, PHP ja andmebaasi juurdepääsu. Seega oli MVC peamine motivatsioon eraldada vaade kiht mudeli kihist. See suurendas mudeli kihi kontrollitavust. Väidetavalt MVC-s ei peaks kiht Vaade ja Mudel üksteist teadma. Selle võimaldamiseks leiutati vahekiht nimega Kontroller. See oli SRP, mida rakendati.

MVC-tsükli näide:

  1. Kasutaja toiming / sündmus vaatekihis (nt värskendustegevus) vallandatakse ja see toiming edastatakse kontrollerile
  2. Kontroller, mis küsib andmeid mudeli kihilt
  3. Mudel modelleerib andmed kontrollerile
  4. Kontroller ütleb, et vaate jaoks värskendage oma olekut uute andmetega
  5. Vaadake tema oleku värskendamist

Apple MVC

IOS-is on vaatekontroller ühendatud UIKiti ja olelustsükli vaatega, seega pole see puhas MVC. Kuid MVC määratluses ei ütle midagi selle kohta, et kontroller ei saa teada konkreetset vaadet või mudelit. Tema peamine eesmärk on eraldada vastutus mudeli kihist vaate kihist, et saaksime seda uuesti kasutada ja mudeli kihti isoleeritult testida.

ViewController sisaldab vaadet ja omab mudelit. Probleemiks on see, et oleme kirjutanud nii kontrolleri koodi kui ka vaatekoodi ViewControllerisse.

MVC loob sageli nn massiivse kuvakontrolleri probleemi, kuid ainult nii juhtub ja sellest saab piisavalt keerukates rakendustes tõsine asi.

On mõned meetodid, mida arendaja saab kasutada vaatekontrolleri hallatavamaks muutmiseks. Mõned näited:

  • VC loogika ekstraheerimine teiste klasside jaoks, näiteks tabelivaate meetodite andmeallikas, ja delegeerige muude failide jaoks, kasutades delegeeritud kujundusmustrit.
  • Looge selgem vastutuse jaotus koosseisuga (nt jagage VC lapsevaate kontrolleriteks).
  • Kasutage koordinaatori kujundusmustrit, et eemaldada vastutus navigatsiooniloogika rakendamise eest VC-s
  • Kasutage DataPresenteri ümbriklassi, mis kapseldab loogika ja muudab andmemudeli andmeväljundiks, mis tähistab lõppkasutajale esitatud andmeid.

MVC vs MVP

Kuidas näete MVP diagrammi, on väga sarnane MVC-ga

MVC oli samm edasi, kuid seda tähistas mõne asja puudumine või vaikus.

Samal ajal kasvas veebivõrk ja arendajate kogukonnas arenes palju asju. Programmeerijad hakkasid näiteks kasutama Ajaxi ja laadima terve HTML-lehe asemel korraga ainult osa lehti.

MVC-s arvan, et miski ei viita sellele, et kontroller ei peaks teadma vaate konkreetset rakendamist (puudumist).

HTML oli osa View kihist ja paljud juhtumid olid nukrad kui kuradima. Mõnel juhul võtab see kasutajalt vastu ainult sündmusi ja kuvab GUI visuaalset sisu.

Kuna veebisaitide osi hakati laadima osadeks, viis see segmenteerimine vaateoleku säilitamise suunas ja suurema vajaduse esitlusloogika vastutuse lahususe järele.

Esitlusloogika on loogika, mis kontrollib, kuidas kasutajaliidest tuleks kuvada ja kuidas kasutajaliidese elemendid koos toimivad. Näide on juhtimisloogika, millal laadimisindikaator peaks näitama / animeerima hakkama ja millal peaks näitamise lõpetama / animeerima.

MVP-s ja MVVM-is peaks vaatekiht olema tuim kui kurat, ilma et selles oleks mingit loogikat või intelligentsust, ning iOS-is peaks vaatekontroller kuuluma kihti. Kui vaade on loll, tähendab see, et isegi esitluse loogika jääb vaatekihist välja.

Üks MVC probleeme on see, et pole selge, kuhu esitusloogika peaks jääma. Ta lihtsalt vaikib sellest. Kas esitluse loogika peaks asuma vaatekihis või mudelikihis?

Kui mudeli roll on lihtsalt „töötlemata” andmete esitamine, tähendab see, et vaate kood oleks järgmine:

Vaatleme järgmist näidet: meil on kasutaja ees- ja perekonnanimega. Vaates peame kuvama kasutajanime kujul „Perekonnanimi, eesnimi“ (nt „Flores, Tiago“).

Kui mudeli roll on pakkuda töötlemata andmeid, tähendab see, et vaade kuvaks järgmist koodi:

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

See tähendab, et kasutajaliidese loogika käitlemine on vaate vastutusel. Kuid see muudab kasutajaliidese loogika ühiskatsetuse võimatuks.

Teiseks lähenemisviisiks on see, et mudel paljastaks ainult andmed, mida tuleb kuvada, peites vaatest kogu äriloogika. Kuid siis jõuame lõpuks mudeliteni, mis käsitlevad nii äri- kui ka kasutajaliidese loogikat. See oleks ühiselt kontrollitav, kuid siis jõuab mudel lõpuni sõltuvusse kaudselt vaatest.

lase nimi = userModel.getDisplayName ()
nameLabel.text = nimi

MVP-l on see selge ja esitlusloogika jääb saatejuhtide kihti. See suurendab Presenteri kihi kontrollitavust. Nüüd on mudel ja saatejuhtkiht hõlpsasti testitavad.

Tavaliselt on MVP teostustes vaade peidetud liidese / protokolli taha ja Presenteris ei tohiks olla ühtegi viidet UIKitile.

Teine asi, mida tuleks meeles pidada, on transitiivsed sõltuvused.

Kui kontrolleril on sõltuvus ärikihist ja ärikihil on andmepöörduskiht sõltuvuses, siis on kontrolleril andmepöörduskihi transiitne sõltuvus. Kuna MVP teostused kasutavad tavaliselt kõigi kihtide vahel lepingut (protokolli), pole sellel transitiivseid sõltuvusi.

Erinevad kihid muutuvad ka erinevatel põhjustel ja erineva kiirusega. Nii et kui kihti muudate, ei soovi te, et see tekitaks teistes kihtides sekundaarseid efekte / probleeme.

Protokollid on stabiilsemad kui klassid. Protokollides pole rakenduse üksikasju ega lepinguid, seega on võimalik kihi rakenduse üksikasju muuta, ilma et see mõjutaks teisi kihte.

Nii loovad lepingud (protokollid) kihtide vahel lahtiühendamise.

MVP vs MVVM

MVVM diagramm

Üks peamisi erinevusi MVP ja MVVM vahel on see, et MVP-s suhtleb saatejuht vaatega liideste kaudu ja MVVM-is on vaade orienteeritud andmete ja sündmuste muutustele.

MVP-s teeme Presenteri ja Vaate vahel käsitsi sidumise liideste / protokollide abil.
MVVM-is muudame andmete automaatse sidumise, kasutades näiteks RxSwift, KVO või geneeriliste ravimite ja sulgemismehhanismidega mehhanismi.

MVVM-is pole meil ViewModeli ja View vahel isegi lepingut (nt: java-liides / iOS-protokoll) vaja, kuna tavaliselt suhtleme vaatleja kujundusmustri kaudu.

MVP kasutab delegaatide mustrit, kuna saatejuhtkiht delegeerib kuvakihi tellimusi, nii et ta peab vaate kohta midagi teadma, isegi kui see on ainult liidese / protokolli allkiri. Mõelge erinevusele teavituskeskuse ja TableView'i delegaatide vahel. Teavituskeskus ei vaja suhtluskanali loomiseks liideseid, kuid TableView Delegates kasutab protokolli, mida klassid peaksid rakendama.

Mõelge laadimisnäidiku esitusloogikast. MVP-s teeb saatejuht ViewProtocol.showLoadingIndicator. MVVM-is võib ViewModel olla isLoading-atribuut. Kiht Vaade automaatse andmeside abil tuvastab, millal see omadus muutub ja end värskendab. MVP on hädavajalikum kui MVVM, kuna saatejuht annab korraldusi.

MVVM on seotud pigem andmemuudatuste kui otseste tellimustega ning me seome andmemuudatuste ja vaatame värskendusi. Kui kasutada koos MVVM-iga RxSwifti ja funktsionaalset reaktiivset programmeerimise paradigmat, oleme koodi muutnud veelgi vähem kohustuslikuks ja deklaratiivsemaks.

MVVM-i on lihtsam testida kui MVP-d, kuna MVVM kasutab vaatleja kujundusmustrit, mis edastab andmeid komponentide vahel lahti ühendatud viisil.
Nii et saame testida lihtsalt andmete muutusi vaadates, lihtsalt kahe objekti võrdlemisega, mitte pilkamise loomise meetodikõnede abil, et testida suhtlust vaate ja saatejuhi vahel.

PS: Tegin artikli mõned uuendused, mis panid selle palju kasvama, nii et oli vaja jagada see kolmeks osaks. Kolmandat osa saate lugeda siit.

Teine osa lõpeb siin. Kogu tagasiside on teretulnud. Kolmas osa räägib VIPERist, VIPist, reaktiivsest programmeerimisest, kompromissidest, piirangutest ja kontekstuaalsest mõjust.

Aitäh, et lugesite! Kui teile see artikkel meeldis, siis palun plaksutage
Other nii et ka teised inimesed saaksid seda lugeda :)