Як выбраць адпаведную архітэктуру iOS (частка 2)

MVC, MVP, MVVM, VIPER або VIP

Вы можаце пракансультавацца з часткай першай тут.

Найбольш важныя архітэктуры iOS

Кароткі агляд.

MVC

Пласты MVC наступныя:

М: бізнес-логіка, сеткавы ўзровень і ўзровень доступу да дадзеных

V: Узровень карыстацкага інтэрфейсу (аб'екты UIKit, раскадроўкі, Xibs)

C: Каардынуе пасярэдніцтва паміж мадэллю і поглядам.

Каб зразумець MVC, нам трэба зразумець кантэкст, у якім ён быў вынайдзены. MVC быў вынайдзены ў старыя часы вэб-распрацоўкі, калі Views не мелі статусу. У былыя часы браўзэр перазагружае ўвесь HTML кожны раз, калі нам патрэбныя візуальныя змены на сайце. У той час не падазравалі, што стан гледжання захоўваецца і захоўваецца.

Напрыклад, былі некаторыя распрацоўшчыкі, якія выкарыстоўвалі адны і тыя ж HTML-файлы, PHP і доступ да баз дадзеных. Такім чынам, асноўнай матывацыяй MVC было аддзяленне ўзроўню прагляду ад узроўню мадэлі. Гэта павялічыла праверка ўзроўню мадэлі. Нібыта ў MVC пласты выгляду і мадэлі не павінны ведаць адзін пра аднаго. Каб зрабіць гэта магчымым, быў вынайдзены прамежкавы пласт, які называецца кантролерам. Гэта быў SRP, які быў ужыты.

Прыклад цыкла MVC:

  1. Актывуецца дзеянне карыстальніка / падзея карыстальніка на ўзроўні прагляду (напрыклад, "дзеянне абнаўлення"), і гэта дзеянне паведамляецца кантролеру
  2. Кантролер, які адпраўляе дадзеныя на ўзровень мадэлі
  3. Мадэлюйце вернутыя дадзеныя кантролеру
  4. Кантролер кажа, што выгляд будзе абнаўляць свой статус новымі дадзенымі
  5. Паглядзець абнаўленне яго стану

Apple MVC

У iOS кантролер прагляду спалучаецца з UIKit і выглядам жыццёвага цыкла, таму гэта не чысты MVC. Аднак у вызначэнні MVC няма нічога, каб сказаць, што кантролер не можа ведаць выгляд або рэалізацыю канкрэтнай мадэлі. Яго асноўная мэта складаецца ў тым, каб аддзяліць абавязкі ўзроўню мадэлі ад узроўню прагляду, каб мы маглі паўторна выкарыстоўваць іх і ізалявана праверыць узровень мадэлі.

ViewController змяшчае выгляд і валодае мадэллю. Праблема ў тым, што мы пішам і код кантролера, і код прагляду ў ViewController.

MVC часта выклікае так званую праблему Massive View Controller, але яна ўзнікае толькі ў прыкладаннях з досыць складанасцю і становіцца сур'ёзным бізнесам.

Існуе некалькі метадаў, якія распрацоўшчык можа зрабіць, каб зрабіць кантролер прагляду больш зразумелым. Некалькі прыкладаў:

  • Вылучыце логіку VC для іншых класаў, такіх як крыніца дадзеных метадаў прагляду табліц, і дэлегуйце для іншых файлаў, выкарыстоўваючы шаблон дызайну дэлегатаў.
  • Стварыце больш дакладную разбіўку абавязкаў па кампазіцыі (напрыклад, разбіццё ВК на элементы кіравання даччыным выглядам).
  • Выкарыстоўвайце шаблон дызайну каардынатара, каб зняць адказнасць за рэалізацыю навігацыйнай логікі ў віртуальным кантролеры
  • Выкарыстоўвайце клас абгорткі DataPresenter, які інкапсулюе логіку і пераўтварае мадэль дадзеных у вывад дадзеных, які прадстаўляе дадзеныя, прадстаўленыя канчатковаму карыстальніку.

MVC супраць MVP

Як вы можаце бачыць схему MVP, MVC вельмі падобны

MVC быў крокам наперад, але ён па-ранейшаму быў адзначаны адсутнасцю ці маўчаннем адносна некаторых рэчаў.

Тым часам Сусветная павуціна разрасталася, і шмат што развівалася ў супольнасці распрацоўшчыкаў. Напрыклад, праграмісты пачалі выкарыстоўваць Ajax і адначасова загружалі толькі часткі старонак замест усёй старонкі HTML.

На мой погляд, у MVC няма ніякіх прыкмет таго, што кантролер не павінен ведаць канкрэтную рэалізацыю View (адсутнасць).

HTML быў часткай слаёў прагляду, і шмат выпадкаў было дурным. У некаторых выпадках ён проста атрымлівае падзеі ад карыстальніка і адлюстроўвае візуальны змест графічнага інтэрфейсу.

Калі часткі вэб-старонак загружаліся па частках, гэтая сегментацыя прывяла да захавання стану прагляду і большай неабходнасці падзяліць абавязкі па логіцы прэзентацыі.

Логіка прэзентацыі - гэта логіка, якая кантралюе, як павінен адлюстроўвацца карыстацкі інтэрфейс і як узаемадзейнічаюць элементы карыстацкага інтэрфейсу. Прыкладам можа служыць логіка кіравання, калі індыкатар загрузкі павінен пачаць паказвацца / аніміравацца, а калі перастаць паказваць / ажыўляць.

У MVP і MVVM пласт прагляду павінен быць настолькі тупым, каб не ўтрымліваць ніякай логікі і інтэлекту, а ў iOS кантролер прагляду павінен быць часткай пласта прагляду. Той факт, што View нямы, азначае, што нават логіка прэзентацыі застаецца па-за межамі плоскасці View.

Адна з праблем MVC заключаецца ў тым, што незразумела, куды павінна ісці логіка прэзентацыі. Ён проста маўчыць пра гэта. Ці павінна быць логіка прэзентацыі ў плоскасці выгляду ці ў плоскасці мадэлі?

Калі роля мадэлі заключаецца ў прадастаўленні толькі "неапрацаваных дадзеных", гэта азначае, што код у прадстаўленні выглядае наступным чынам:

Разгледзім наступны прыклад: У нас ёсць карыстальнік з імем і прозвішчам. У праглядзе мы павінны паказаць імя карыстальніка як "Прозвішча, імя" (напрыклад, "Flores, Tiago").

Калі роля мадэлі заключаецца ў прадастаўленні "неапрацаваных дадзеных", гэта азначае, што код у прадстаўленні выглядае наступным чынам:

хай firstName = userModel.getFirstName () хай lastName = userModel.getLastName () nameLabel.text = Прозвішча + “,“ + Імя

Гэта азначае, што View адказвае за апрацоўку логікі карыстацкага інтэрфейсу. Аднак гэта робіць немагчымым модульнае тэставанне логікі карыстацкага інтэрфейсу.

Іншы падыход заключаецца ў тым, каб дазволіць мадэлі паказваць толькі тыя дадзеныя, якія неабходна паказаць, і хаваць бізнес-логіку ад прагляду. Але ў нас ёсць мадэлі, якія працуюць як з бізнес-логікай, так і з логікай карыстацкага інтэрфейсу. Гэта было б правераным аб'ектам, але тады мадэль імпліцытна залежыць ад выгляду.

хай name = userModel.getDisplayName () nameLabel.text = імя

MVP гэта зразумела, і логіка прэзентацыі застаецца на ўзроўні вядучага. Гэта павялічвае праверка ўзроўню вядучага. Цяпер пласт і мадэль вядучага можна праверыць без праблем.

Звычайна ў рэалізацыях MVP выгляд схаваны за інтэрфейсам / пратаколам, і ў прэзентатары не павінна быць спасылак на UIKit.

Трэба адзначыць яшчэ і пераходныя залежнасці.

Калі кантролер мае ў якасці залежнасці бізнес-узровень, а бізнес-ўзровень у якасці залежнасці мае ўзровень доступу да дадзеных, кантролер мае пераходную залежнасць для ўзроўню доступу да дадзеных. Паколькі рэалізацыі MVP звычайна выкарыстоўваюць кантракт (пратакол) паміж усімі ўзроўнямі, пераходных залежнасцей няма.

Розныя пласты таксама мяняюцца па розных прычынах і з рознай хуткасцю. Такім чынам, калі вы пераключыцеся на адзін узровень, гэта не павінна выклікаць другасных эфектаў / праблем на іншых узроўнях.

Пратаколы больш стабільныя, чым класы. Журналы не ўтрымліваюць ніякіх дэталяў рэалізацыі і не звязаны з кантрактамі. Такім чынам, можна змяніць дэталі рэалізацыі аднаго ўзроўню, не закранаючы іншыя ўзроўні.

Кантракты (пратаколы) ствараюць развязку паміж пластамі.

MVP супраць MVVM

Схема MVVM

Адным з асноўных адрозненняў паміж MVP і MVVM з'яўляецца тое, што ў MVP вядучы інтэрфейсуе з выглядам, а ў MVVM выгляд накіраваны на змены дадзеных і падзей.

У MVP мы ствараем ручную сувязь паміж вядучым і праглядам з выкарыстаннем інтэрфейсаў / пратаколаў. У MVVM мы ажыццяўляем аўтаматычнае прывязка дадзеных з RxSwift, KVO або механізмам з агульнымі прэпаратамі і закрыццямі.

У MVVM нам нават не патрэбны кантракт (напрыклад, інтэрфейс Java / пратакол iOS) паміж ViewModel і View, бо звычайна мы маем зносіны праз шаблон дызайну назіральнікаў.

MVP выкарыстоўвае шаблон дэлегата, таму што ўзровень прэзентацыі дэлегуе каманды на ўзровень прагляду. Такім чынам, яму трэба нешта ведаць пра выгляд, нават калі гэта проста подпіс інтэрфейсу / пратакола. Падумайце пра розніцу паміж дэлегатамі Цэнтра апавяшчэнняў і TableView. Цэнтру апавяшчэнняў не патрэбны ніякія інтэрфейсы для стварэння канала сувязі. Аднак TableView Delegates выкарыстоўвае пратакол, які павінны рэалізоўваць класы.

Падумайце аб логіцы прэзентацыі індыкатара зарада. У MVP вядучы запускае ViewProtocol.showLoadingIndicator. У MVVM у ViewModel можа быць уласцівасць isLoading. Узровень прагляду выкарыстоўвае аўтаматычную прывязку дадзеных, каб распазнаць, калі гэта ўласцівасць змяняецца і абнаўляецца. MVP больш пераканаўчы, чым MVVM, таму што вядучы выдае каманды.

MVVM больш тычыцца змены дадзеных, чым прамых заказаў, і мы звязваем змены дадзеных для прагляду абнаўленняў. Калі мы выкарыстоўваем RxSwift і функцыянальную парадыгму рэактыўнага праграмавання разам з MVVM, мы зрабілі код яшчэ менш пераканаўчым і больш дэкларатыўным.

MVVM прасцей пратэставаць, чым MVP, бо MVVM выкарыстоўвае шаблон дызайну назіральніка, які перадае дадзеныя паміж кампанентамі ў раз'яднаным парадку. Такім чынам, мы можам праверыць, проста паглядзеўшы змены ў дадзеных, параўноўваючы два аб'екты, а не здзекуючыся з выклікаў метадаў, каб праверыць сувязь паміж выглядам і вядучым.

PS: Я зрабіў некалькі абнаўленняў для элемента, які прымусіў яго значна расці. Таму трэба было падзяліць яго на тры часткі. Трэцюю частку вы можаце прачытаць тут.

Частка другая тут заканчваецца. Усе водгукі вітаюцца. Частка трэцяя - пра VIPER, VIP, рэактыўнае праграмаванне, кампрамісы, абмежаванні і кантэкстнае пачуццё.

Дзякуй за чытанне! Калі вам спадабаўся гэты артыкул, папляскайце p, каб і іншыя маглі яго прачытаць :)