Kako odabrati odgovarajuću arhitekturu iOS (2. dio)

MVC, MVP, MVVM, VIPER ili VIP

Ovdje možete konzultirati prvi dio.

Glavne arhitekture iOS-a

Kratak pregled.

MVC

MVC slojevi su kako slijedi:

M: Poslovna logika, mrežni sloj i sloj pristupa podacima

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

C: Koordinira posredovanje između modela i pogleda.

Da bismo razumjeli MVC, moramo razumjeti kontekst u kojem je on izumljen. MVC je izumljen u starim danima web razvoja, gdje Views nema stanje. U stara vremena kad god nam je potrebna vizualna promjena na web mjestu, preglednik ponovno učita cijeli HTML. U to vrijeme nije postojao koncept stanja pogleda i održavanja.

Na primjer, bilo je nekih programera koji su se miješali unutar iste HTML datoteke, PHP-a i pristupa bazi podataka. Dakle, glavna motivacija MVC-a bila je odvajanje sloja View od sloja modela. To je povećalo proverljivost sloja modela. Navodno u MVC-u sloj View i Model ne bi trebao ništa znati jedni o drugima. Kako bi to bilo moguće, izumljen je posrednički sloj pod nazivom Controller. Ovo je bio SRP koji je primijenjen.

Primjer MVC ciklusa:

  1. Korisnička radnja / događaj u sloju prikaza (npr. Osvježi radnju) pokreće se i ta se radnja priopćava Upravljaču
  2. Kontroler koji postavlja podatke u Sloj modela
  3. Modelirajte vraća podatke u kontroler
  4. Controller kaže da će View ažurirati svoje stanje s novim podacima
  5. Pogledajte ažurirajte njegovo stanje

Apple MVC

U iOS-u je View Controller spojen s UIKit-om i prikazom životnog ciklusa, tako da to nije čisti MVC. Međutim, u definiciji MVC ne može se reći da kontroler ne može znati specifičnu implementaciju View ili Model. Njegova je glavna svrha razdvajanje odgovornosti sloja modela od sloja View kako bismo ga mogli ponovo koristiti i testirati sloj modela izolirano.

ViewController sadrži Pogled i posjeduje Model. Problem je što smo koristili za pisanje koda kontrolera, kao i kod za prikaz u ViewController.

MVC često stvara problem zvan Massive View Controller, ali to se događa i postaje ozbiljna stvar u aplikacijama s dovoljno složenosti.

Postoje neke metode koje programer može upotrijebiti kako bi View Controller bio upravljiviji. Neki primjeri:

  • Izdvajanje logike VC-a za druge klase, poput prikaza tablice, izvor podataka i delegat za ostale datoteke pomoću obrasca dizajna delegita.
  • Napravite jasniju podjelu odgovornosti sa sastavom (npr. Podijelite VC na kontrolere dječjeg nadzora).
  • Koristite obrazac dizajna koordinatora za uklanjanje odgovornosti za implementaciju navigacijske logike u VC-u
  • Koristite DataPresenter klasu omota koja enkapsulira logiku i pretvara model podataka u izlaz podataka koji predstavljaju podatke predstavljene krajnjem korisniku.

MVC vs MVP

Kako možete vidjeti dijagram MVP-a vrlo je sličan MVC-u

MVC je bio korak naprijed, ali i dalje ga je obilježavala odsutnost ili tišina o nekim stvarima.

U međuvremenu, svjetska mreža rasla je i mnoge su se stvari u zajednici programera razvijale. Primjerice, programeri su počeli koristiti Ajax i učitavali samo dijelove stranica umjesto cijele HTML stranice odjednom.

U MVC-u mislim da nema ničega što bi ukazivalo na to da Kontrolor ne bi trebao znati specifičnu implementaciju Viewa (odsutnosti).

HTML je bio dio View sloja i mnogi su slučajevi bili glupi. U nekim slučajevima prima događaje samo od korisnika i prikazuje vizualni sadržaj GUI-ja.

Kako su se dijelovi web stranica počeli učitavati u dijelove, ova segmentacija vodila je u smjeru održavanja View stanja i veće potrebe za odvajanjem odgovornosti logike prezentacije.

Logika prezentacije je logika koja kontrolira kako UI bi trebao biti prikazan i kako elementi UI međusobno djeluju. Primjer je kontrolna logika kada indikator učitavanja treba početi prikazivati ​​/ animirati i kada bi se trebao prestati prikazivati ​​/ animirati.

U MVP-u i MVVM-u bi sloj prikaza trebao biti glup kao kurac, bez ikakve logike ili inteligencije, a u iOS-u bi kontroler pogleda trebao biti dio View Layer-a. Činjenica da je View glup znači da čak i logika prezentacije ostaje izvan sloja View.

Jedan od problema MVC-a je taj što nije jasno gdje bi logika prezentacije trebala ostati. Na to on jednostavno šuti. Bi li logika prezentacije trebala biti u sloju View ili u sloju modela?

Ako je uloga modela samo pružanje "sirovih" podataka, to znači da bi kod u vlasničkom pregledu bio:

Razmotrimo sljedeći primjer: imamo korisnika, s imenom i prezimenom. U prikazu moramo prikazati korisničko ime kao "Prezime, ime" (npr. "Flores, Tiago").

Ako je uloga modela pružanje "sirovih" podataka, to znači da bi kod u vlasničkom pregledu bio:

neka firstName = userModel.getFirstName ()
neka lastName = userModel.getLastName ()
nameLabel.text = lastName + "," + firstName

Dakle, to znači da bi odgovornost bila za upravljanje logikom sučelja. Ali to onemogućuje jedinstvenu logiku korisničkog sučelja.

Drugi je pristup da se Model izloži samo podacima koji trebaju biti prikazani, skrivajući bilo koju poslovnu logiku iz pogleda. Ali tada završimo s modelima koji upravljaju i poslovnom i korisničkom sučeljem. Bilo bi testiranje jedinice, ali tada model završava, implicirano ovisan o pogledu.

neka ime = korisnikModel.getDisplayName ()
nameLabel.text = ime

MVP je jasan po tome, a logika prezentacije ostaje na nivou prezentacijskog sloja. To povećava proverljivost sloja Presenter. Sada se model i sloj prezentatora lako testiraju.

U MVP implementacijama, prikaz je normalno skriven iza sučelja / protokola i ne bi trebalo biti reference na UIKit u Presenteru.

Još jedna stvar koju treba imati na umu su tranzitivne ovisnosti.

Ako kontroler ima poslovni sloj kao ovisnost, a poslovni sloj ima sloj pristupa podacima kao ovisnost, tada kontroler ima tranzitivnu ovisnost za sloj pristupa podacima. Budući da MVP implementacije obično koriste ugovor (protokol) između svih slojeva, to nema tranzitivne ovisnosti.

Različiti slojevi se također mijenjaju iz različitih razloga i različitim brzinama. Dakle, kada promijenite sloj, ne želite da to uzrokuje sekundarne efekte / probleme na ostalim slojevima.

Protokoli su stabilniji od klasa. Protokoli nemaju detalje implementacije i s ugovorima, tako da je moguće promijeniti detalje implementacije sloja bez utjecaja na ostale slojeve.

Dakle, ugovori (protokoli) stvaraju razdvajanje između slojeva.

MVP vs MVVM

MVVM dijagram

Jedna od glavnih razlika između MVP-a i MVVM-a je ta što u MVP-u Presenter komunicira s pogledom putem sučelja, a u MVVM-u je pogled usmjeren na promjene podataka i događaja.

U MVP-u izrađujemo ručno povezivanje između Presenter-a i View-a pomoću sučelja / protokola.
U MVVM-u izrađujemo automatsko povezivanje podataka koristeći nešto poput RxSwift, KVO ili upotrebljavamo mehanizam s generičkim podacima i zatvaračima.

U MVVM-u nam čak i nije potreban ugovor (npr. Java sučelje / iOS protokol) između ViewModel-a i View-a jer obično komuniciramo putem Observer Design Pattern.

MVP koristi uzorak delegitata jer Presenter Layer Delegates naređuje na Layer View, pa mora znati nešto o pogledu, čak i ako je samo potpis sučelja / protokola. Razmislite o razlici između centra za obavijesti i TableView delegata. Centru za obavijesti nisu potrebna sučelja za stvaranje komunikacijskog kanala, ali TableView Delegates koristi protokol koji bi klase trebali implementirati.

Razmislite o logici prezentacije indikatora opterećenja. Na MVP-u prezentator radi ViewProtocol.showLoadingIndicator. U MVVM-u može postojati svojstvo isLoading u ViewModelu. Sloj prikaza putem automatskog povezivanja podataka otkriva kada se ovo svojstvo promijeni i osvježi. MVP je imperativniji od MVVM-a jer Presenter daje naredbe.

MVVM je više o promjenama podataka nego izravnim narudžbama i mi povezujemo promjene podataka i pregledavamo ažuriranja. Ako koristimo RxSwift i funkcionalnu paradigmu reaktivnog programiranja zajedno s MVVM, kod smo učinili još manje imperativnim i deklarativnijim.

MVVM je lakši za testiranje od MVP-a, jer MVVM koristi obrazac dizajna promatrača koji na različite načine prenosi podatke između komponenata.
Tako da možemo testirati samo gledanjem promjena podataka samo usporedbom dva objekta, a ne stvaranjem ismijavanja metoda poziva za testiranje komunikacije između Viewa i Presentera.

PS: Napravio sam neka ažuriranja članka zbog kojih je puno porastao, pa ga je bilo potrebno podijeliti u tri dijela. Treći dio možete pročitati ovdje.

Drugi dio završava ovdje. Sve su povratne informacije dobrodošle. Treći dio će govoriti o VIPER-u, VIP-u, reaktivnom programiranju, kompromisima, ograničenjima i kontekstualnom smislu.

Hvala na čitanju! Ako vam se svidio ovaj članak, pljeskajte
tako da i drugi mogu to čitati :)