Paano Piliin ang Naaangkop na iOS Architecture (Bahagi 2)

MVC, MVP, MVVM, VIPER o VIP

Maaari kang kumonsulta sa bahagi ng isa dito.

Ang pinakamahalagang mga arkitektura ng iOS

Isang maikling pangkalahatang ideya.

MVC

Ang mga layer ng MVC ay ang mga sumusunod:

M: lohika sa negosyo, layer ng network at layer ng pag-access ng data

V: Antas ng UI (Mga bagay sa UIKit, storyboard, Xibs)

C: Coordinates ang pamamagitan sa pagitan ng modelo at pagtingin.

Upang maunawaan ang MVC kailangan nating maunawaan ang konteksto kung saan ito ay imbento. Ang MVC ay naimbento sa mga lumang araw ng pagbuo ng web nang walang katayuan ang Views. Sa mga nagdaang araw, muling nilulunsad ng browser ang lahat ng HTML sa tuwing kailangan namin ng isang visual na pagbabago sa website. Sa oras na iyon, walang ideya na ang estado ng paningin ay nagpursige at nai-save.

Halimbawa, may ilang mga developer na gumamit ng parehong mga HTML file, PHP at pag-access sa database. Kaya't ang pangunahing pagganyak ng MVC ay paghiwalayin ang antas ng pagtingin mula sa antas ng modelo. Nadagdagan nito ang kakayahang masubukan ang antas ng modelo. Diumano sa MVC hindi dapat malaman ng mga layer ng view at modelo ang tungkol sa bawat isa. Upang gawing posible ito, isang intermediate layer na tinatawag na isang controller ay naimbento. Ito ang inilapat na SRP.

Isang halimbawa ng ikot ng MVC:

  1. Ang isang pagkilos ng gumagamit / isang kaganapan ng gumagamit sa antas ng pagtingin (hal. "Pag-update ng pagkilos") ay na-trigger at ang aksyon na ito ay naiparating sa controller
  2. Ang controller na nagpapadala ng data sa antas ng modelo
  3. I-modelo ang ibinalik na data sa controller
  4. Sinasabi ng tagontrol na i-update ng view ang katayuan nito sa bagong data
  5. Tingnan ang i-update ang estado nito

Apple MVC

Sa iOS, ang View Controller ay isinama sa UIKit at view ng lifecycle, kaya't ito ay hindi isang purong MVC. Gayunpaman, sa kahulugan ng MVC walang sasabihin na ang controller ay hindi maaaring malaman ang view o tiyak na pagpapatupad ng modelo. Ang pangunahing layunin nito ay paghiwalayin ang mga responsibilidad ng antas ng modelo mula sa antas ng pagtingin upang magamit namin muli ang mga ito at subukan ang antas ng modelo na ihiwalay.

Naglalaman ang ViewController ng view at nagmamay-ari ng modelo. Ang problema ay nagsusulat kami ng parehong code ng controller at ang view code sa ViewController.

Madalas na sanhi ng MVC ang tinatawag na problema ng Massive View Controller, ngunit nangyayari lamang ito sa mga app na may sapat na pagiging kumplikado at nagiging seryosong negosyo.

Mayroong ilang mga pamamaraan na maaaring magamit ng developer upang gawing mas malinaw ang View Controller. Ilang halimbawa:

  • I-extract ang VC lohika para sa iba pang mga klase tulad ng mapagkukunan ng data ng mga pamamaraan ng pagtingin sa talahanayan at italaga para sa iba pang mga file gamit ang pattern ng disenyo ng delegado.
  • Lumikha ng isang mas malinaw na pagkasira ng mga responsibilidad sa komposisyon (hal., Paghati sa VC sa mga kontrol ng pagtingin sa bata).
  • Gamitin ang pattern ng disenyo ng coordinator upang alisin ang responsibilidad para sa pagpapatupad ng nabigasyon na lohika sa virtual controller
  • Gumamit ng isang klase ng DataPresenter wrapper na nag-encapsulate ng lohika at binabago ang modelo ng data sa output ng data na kumakatawan sa data na ipinakita sa end user.

MVC kumpara sa MVP

Tulad ng nakikita mo ang diagram ni MVP, ang MVC ay halos magkatulad

Ang MVC ay isang hakbang pasulong, ngunit minarkahan pa rin ito ng kawalan o katahimikan tungkol sa ilang mga bagay.

Pansamantala, lumago ang World Wide Web at maraming mga bagay na binuo sa komunidad ng developer. Halimbawa, nagsimulang gumamit ang mga programmer ng Ajax at naglo-load lamang ng mga bahagi ng mga pahina sa halip na ang buong pahina ng HTML nang sabay-sabay.

Sa MVC, sa palagay ko, walang pahiwatig na hindi alam ng taga-kontrol ang tiyak na pagpapatupad ng View (kawalan).

Ang HTML ay bahagi ng layer ng view, at maraming mga kaso ang bobo. Sa ilang mga kaso, nakakatanggap lamang ito ng mga kaganapan mula sa gumagamit at ipinapakita ang visual na nilalaman ng GUI.

Tulad ng mga bahagi ng mga web page na na-load sa mga bahagi, ang paghihiwalay na ito ay humantong sa pagpapanatili ng estado ng view at isang higit na pangangailangan na paghiwalayin ang mga responsibilidad para sa pagtatanghal na lohika.

Ang lohika sa pagtatanghal ay ang lohika na kumokontrol kung paano dapat ipakita ang interface ng gumagamit at kung paano nakikipag-ugnayan ang mga elemento ng interface ng gumagamit sa bawat isa. Ang isang halimbawa ay ang lohika ng pagkontrol kung kailan dapat magsimulang magpakita / mag-animate ang isang tagapagpahiwatig ng paglo-load at kung kailan dapat itong tumigil sa pagpapakita / pag-animate.

Sa MVP at MVVM, ang view layer ay dapat na maloko na wala itong nilalaman na lohika o intelihensiya, at sa iOS ang view controller ay dapat na bahagi ng layer ng view. Ang katotohanan na ang View ay pipi ay nangangahulugan na kahit na ang pagtatanghal na lohika ay nananatili sa labas ng View eroplano.

Isa sa mga problema sa MVC ay hindi malinaw kung saan dapat pumunta ang presentasyon. Siya ay tahimik lamang tungkol dito. Dapat bang ang lohika sa pagtatanghal ay nasa view na eroplano o sa modelong eroplano?

Kung ang papel na ginagampanan ng modelo ay ang magbigay lamang ng "hilaw na data", nangangahulugan ito na ang code sa pagtingin ay ang mga sumusunod:

Isaalang-alang ang sumusunod na halimbawa: Mayroon kaming isang gumagamit na may una at apelyido. Sa view kailangan naming ipakita ang username bilang "Huling Pangalan, Unang Pangalan" (hal. "Flores, Tiago").

Kung ang papel na ginagampanan ng modelo ay upang ibigay ang "hilaw na data", nangangahulugan ito na ang code sa view ay ang mga sumusunod:

let firstName = userModel.getFirstName () let lastName = userModel.getLastName () nameLabel.text = Last Name + “,“ + First Name

Nangangahulugan ito na responsibilidad ni View na hawakan ang lohika ng interface ng gumagamit. Gayunpaman, ginagawang imposibleng i-test ng unit ang lohika ng interface ng gumagamit.

Ang iba pang diskarte ay hayaan ang modelo na ipakita lamang ang data na kailangang ipakita at itago ang lohika ng negosyo mula sa pagtingin. Ngunit mayroon kaming mga modelo na humahawak sa parehong lohika sa negosyo at lohika ng interface ng gumagamit. Ito ay magiging isang nasusubok na nilalang, ngunit pagkatapos ang modelo ay implicit na tingnan ang umaasa.

hayaan ang pangalan = userModel.getDisplayName () nameLabel.text = pangalan

Ito ay malinaw sa MVP at ang pagtatanghal na lohika ay nananatili sa antas ng nagtatanghal. Dagdagan nito ang kakayahang masubukan ang antas ng nagtatanghal. Ngayon ang modelo ng layer at nagtatanghal ay maaaring masubukan nang walang anumang mga problema.

Karaniwan sa mga pagpapatupad ng MVP ang view ay nakatago sa likod ng isang interface / protocol at dapat walang mga sanggunian sa UIKit sa nagtatanghal.

Ang isa pang bagay na dapat tandaan ay ang mga palipat na pagtitiwala.

Kung ang controller ay may isang layer ng negosyo bilang isang dependency at ang layer ng negosyo ay may isang layer ng pag-access ng data bilang isang dependency, ang controller ay may isang palipat na pagtitiwala para sa layer ng pag-access ng data. Dahil ang mga pagpapatupad ng MVP ay karaniwang gumagamit ng isang kontrata (protocol) sa pagitan ng lahat ng mga antas, walang mga palipat na pagtitiwala.

Nagbabago rin ang iba't ibang mga layer para sa iba't ibang mga kadahilanan at sa iba't ibang mga rate. Kaya kung lumipat ka ng isang antas, hindi ito dapat maging sanhi ng pangalawang epekto / mga problema sa iba pang mga antas.

Ang mga protokol ay mas matatag kaysa sa mga klase. Ang mga log ay hindi naglalaman ng anumang mga detalye sa pagpapatupad at hindi naka-link sa mga kontrata. Samakatuwid, posible na baguhin ang mga detalye ng pagpapatupad ng isang antas nang hindi nakakaapekto sa iba pang mga antas.

Ang mga kontrata (mga protocol) ay lumilikha ng isang decoupling sa pagitan ng mga layer.

MVP kumpara sa MVVM

Diagram ng MVVM

Ang isa sa mga pangunahing pagkakaiba sa pagitan ng MVP at MVVM ay ang sa MVP ang interface ng nagtatanghal sa pagtingin, at sa MVVM ang view ay nakatuon sa mga pagbabago sa data at kaganapan.

Sa Ang MVP lumikha kami ng isang manu-manong link sa pagitan ng nagtatanghal at pagtingin gamit ang mga interface / protokol. Sa MVVM nagsasagawa kami ng isang awtomatikong pagbubuklod ng data sa RxSwift, KVO o isang mekanismo na may mga generics at pagsasara.

Sa MVVM hindi na namin kailangan ng isang kontrata (hal. Java interface / iOS protocol) sa pagitan ng ViewModel at View, dahil normal kaming nakikipag-usap sa pamamagitan ng pattern ng Disenyo ng Observer.

Gumagamit ang MVP ng pattern ng delegado sapagkat ang nagtatanghal na layer ng delegado ay nag-uutos sa view layer. Samakatuwid, kailangan niyang malaman ang isang bagay tungkol sa pagtingin, kahit na ang interface lamang ng interface / protocol. Isipin ang pagkakaiba sa pagitan ng mga delegado ng Notification Center at TableView. Ang Notification Center ay hindi nangangailangan ng anumang mga interface upang lumikha ng isang channel sa komunikasyon. Gayunpaman, gumagamit ang TableView Delegates ng isang protokol na dapat ipatupad ng mga klase.

Isipin ang lohika sa pagtatanghal ng isang tagapagpahiwatig ng pagsingil. Sa MVP, pinapatakbo ng nagtatanghal ang ViewProtocol.showLoadingIndicator. Sa MVVM, maaaring mayroong isang isLoading na pag-aari sa ViewModel. Gumagamit ang view layer ng awtomatikong pagbubuklod ng data upang makilala kapag nagbago ang pag-aari na ito at ina-update ang sarili nito. Mas nakakaengganyo ang MVP kaysa sa MVVM dahil naglalabas ng utos ang nagtatanghal.

Ang MVVM ay higit pa tungkol sa mga pagbabago sa data kaysa sa mga direktang order, at na-link namin ang mga pagbabago sa data upang matingnan ang mga pag-update. Kapag gumagamit kami ng RxSwift at isang functional reactive program paradigm kasama ang MVVM, ginawa namin ang code kahit na hindi gaanong nakakaengganyo at mas nagpapahayag.

Ang MVVM ay mas madaling subukan kaysa sa MVP, dahil ginagamit ng MVVM ang pattern ng Disenyo ng Observer, na naglilipat ng data sa pagitan ng mga bahagi sa isang nadoble na pamamaraan. Kaya't maaari nating subukan sa pamamagitan lamang ng pagtingin sa mga pagbabago sa data sa pamamagitan ng paghahambing ng dalawang bagay, sa halip na bugyain ang mga tawag sa pamamaraan upang subukan ang komunikasyon sa pagitan ng view at ng nagtatanghal.

PS: Gumawa ako ng ilang mga pag-update sa item na nagpalaki nito nang husto. Samakatuwid kinakailangan na hatiin ito sa tatlong bahagi. Maaari mong basahin ang ikatlong bahagi dito.

Nagtatapos ang bahaging dalawa dito. Malugod na tinatanggap ang lahat ng puna. Ikatlong bahagi ay tungkol sa VIPER, VIP, Reactive Programming, Trade-Offs, Constraints at Contextual Sense.

Salamat sa pagbabasa! Kung nasiyahan ka sa artikulong ito, mangyaring pumalakpak upang mabasa din ito ng iba :)