Bagaimana untuk memilih Architecture iOS yang sesuai (Bahagian 2)

MVC, MVP, MVVM, VIPER, atau VIP

Anda boleh berunding dengan bahagian ini di sini.

Arkib Utama IOS

Gambaran ringkas.

MVC

Lapisan MVC adalah seperti berikut:

M: Logik Perniagaan, Lapisan Rangkaian dan Lapisan Akses Data

V: UI Layer (perkara UIKit, Storyboard, Xibs)

C: Menyelaras pengantaraan antara Model dan Lihat.

Untuk memahami MVC kita harus memahami konteks di mana ia dicipta. MVC dicipta pada hari-hari pembangunan Web lama, di mana Pandangan tidak mempunyai keadaan. Pada masa yang lama setiap kali kita memerlukan perubahan visual dalam laman web, pelayar memuatkan semula keseluruhan HTML sekali lagi. Pada masa itu tidak ada konsep keadaan pandangan yang dikekalkan dan disimpan.

Sebagai contoh, terdapat beberapa pemaju yang bercampur dalam file HTML yang sama, PHP dan akses pangkalan data. Jadi motivasi utama MVC adalah untuk memisahkan lapisan Lihat dari lapisan Model. Ini meningkatkan ketelusan lapisan Model. Seharusnya di MVC, Lapisan Lihat dan Model tidak perlu tahu apa-apa tentang satu sama lain. Untuk membuat ini mungkin, lapisan perantara bernama Pengawal dicipta. Inilah SRP yang digunakan.

Satu contoh kitaran MVC:

  1. Tindakan pengguna / peristiwa dalam Lihat Layer (contohnya: Refresh Action) dipecat dan tindakan itu disampaikan kepada Pengawal
  2. Pengawal yang meminta data kepada Model Layer
  3. Model data pulangan kepada Pengawal
  4. Pengawal mengatakan untuk melihat mengemas kini keadaannya dengan Data baru
  5. Lihat kemas kini keadaannya

Apple MVC

Dalam IOS, Pengawal Lihat ditambah kepada UIKit dan paparan hayat kitaran, jadi ia bukan murni MVC. Walau bagaimanapun, dalam definisi MVC, tidak ada yang mengatakan bahawa Pengawal tidak dapat mengetahui pelaksanaan Paparan atau Model tertentu. Tujuan utamanya adalah untuk memisahkan tanggungjawab lapisan Model dari lapisan Lihat supaya kita dapat menggunakannya semula dan menguji lapisan Model secara berasingan.

The ViewController mengandungi View dan memiliki Model. Masalahnya kita gunakan untuk menulis kod pengawal serta kod pandangan dalam ViewController.

MVC sering mencipta masalah Massive View Controller yang dipanggil, tetapi itu hanya berlaku dan menjadi perkara yang serius dalam aplikasi dengan kerumitan yang cukup.

Terdapat beberapa kaedah yang boleh digunakan oleh pemaju untuk menjadikan View Controller lebih mudah diurus. Beberapa contoh:

  • Mengekstrak logik VC untuk kelas lain seperti sumber data kaedah paparan jadual dan mewakilkan untuk fail lain menggunakan corak reka bentuk perwakilan.
  • Buat pemisahan tanggungjawab yang lebih berbeza dengan komposisi (cth. Split VC ke pengawal pandangan kanak-kanak).
  • Gunakan pola reka bentuk penyelaras untuk menghapuskan tanggungjawab melaksanakan logik navigasi di VC
  • Gunakan kelas pembungkusan DataPresenter yang merangkumi logik dan mengubah model data ke output data yang mewakili data yang dikemukakan kepada pengguna akhir.

MVC vs MVP

Bagaimana anda boleh melihat gambarajah MVP adalah sangat serupa dengan MVC

MVC adalah satu langkah ke hadapan, tetapi ia masih ditandai dengan ketiadaan atau kesunyian tentang beberapa perkara.

Sementara itu, World Wide Web berkembang dan banyak perkara dalam komuniti pemaju berkembang. Sebagai contoh, pengaturcara mula menggunakan Ajax dan hanya memuatkan bahagian halaman dan bukannya halaman HTML sepenuhnya sekaligus.

Di MVC saya fikir tiada apa-apa untuk menunjukkan bahawa Pengawal tidak sepatutnya mengetahui pelaksanaan tertentu View (ketiadaan).

HTML adalah sebahagian daripada lapisan Lihat dan banyak kes yang bodoh sebagai fuck. Dalam sesetengah kes, ia hanya menerima peristiwa dari pengguna dan memaparkan kandungan visual GUI.

Oleh kerana sebahagian daripada halaman web mula dimuatkan ke dalam bahagian, segmentasi ini diterajui ke arah mengekalkan keadaan Lihat dan keperluan yang lebih besar untuk pemisahan tanggungjawab logik pembentangan.

Logik persembahan adalah logik yang mengawal bagaimana UI perlu dipaparkan dan bagaimana elemen UI berinteraksi bersama. Contohnya ialah logik kawalan apabila Petunjuk pemuatan sepatutnya mula menunjukkan / bernyawa dan apabila ia sepatutnya berhenti menunjukkan / bernyawa.

Dalam MVP dan MVVM, Layer Lihat sepatutnya bodoh sebagai fuck tanpa apa-apa logik atau kepintaran di dalamnya, dan dalam IOS, Pengawal Lihat hendaklah menjadi sebahagian daripada Layer Lihat. Fakta Lihat yang bodoh bermaksud bahawa walaupun logik persembahan tetap keluar dari lapisan Lihat.

Salah satu masalah MVC adalah bahawa ia tidak jelas tentang mana logik persembahan harus kekal. Dia hanya diam tentang perkara itu. Sekiranya logik penyampaian berada di lapisan Lihat atau dalam Lapisan Model?

Sekiranya peranan Model adalah hanya menyediakan data "mentah", itu bermakna kod dalam View akan:

Pertimbangkan contoh berikut: kami mempunyai Pengguna, dengan nama pertama dan nama belakang. Dalam Paparan, kita perlu memaparkan nama pengguna sebagai "Nama Akhir, Nama Pertama" (cth. "Flores, Tiago").

Jika peranan Model adalah untuk menyediakan data "mentah", itu bermakna kod dalam View akan:

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

Jadi ini bermakna bahawa ia akan menjadi tanggungjawab Lihat pengendalian logik UI. Tetapi ini menjadikan logik UI mustahil untuk ujian unit.

Pendekatan lain adalah dengan Model hanya mendedahkan data yang perlu dipaparkan, menyembunyikan sebarang logik perniagaan dari Lihat. Tetapi kemudian, kita berakhir dengan Model yang mengendalikan kedua-dua perniagaan dan logik UI. Ia akan menjadi unit yang boleh diuji, tetapi Model berakhir, secara tersirat bergantung pada View.

mari nama = userModel.getDisplayName ()
nameLabel.text = nama

MVP jelas mengenai perkara itu dan logik persembahan kekal di Layer Presenter. Ini meningkatkan keterangan lapisan Presenter. Kini Model dan Layer Presenter mudah diuji.

Biasanya dalam pelaksanaan MVP, Lihat disembunyikan di belakang antara muka / protokol dan tidak perlu ada sebutan kepada UIKit dalam Presenter.

Satu lagi perkara yang perlu diingat ialah pergantungan transitif.

Jika Pengawal mempunyai Lapisan Perniagaan sebagai pergantungan dan Layer Perniagaan mempunyai Lapisan Akses Data sebagai pergantungan, maka Pengawal mempunyai ketergantungan transitif untuk Lapisan Akses Data. Sejak pelaksanaan MVP biasanya menggunakan kontrak (protokol) di antara semua lapisan yang tidak mempunyai dependensi transitif.

Lapisan yang berbeza juga berubah atas sebab yang berbeza dan pada kadar yang berbeza. Oleh itu, apabila anda menukar lapisan anda tidak mahu ini menyebabkan kesan sekunder / masalah dalam lapisan lain.

Protokol lebih stabil daripada kelas. Protokol ini tidak mempunyai butiran pelaksanaan dan dengan kontrak, jadi mungkin untuk mengubah detail pelaksanaan lapisan tanpa mempengaruhi lapisan lain.

Oleh itu, kontrak (protokol) membuat dekop antara lapisan.

MVP vs MVVM

Rajah MVVM

Salah satu perbezaan utama antara MVP dan MVVM adalah bahawa dalam MVP, Presenter berkomunikasi dengan View melalui antara muka, dan dalam MVVM, View berorientasikan kepada perubahan data dan peristiwa.

Dalam The MVP kami membuat manual mengikat antara Presenter dan View menggunakan Antara muka / Protokol.
Dalam MVVM kita membuat data automatik mengikat menggunakan sesuatu seperti RxSwift, KVO atau menggunakan mekanisme dengan generik dan penutupan.

Dalam MVVM kita juga tidak memerlukan kontrak (misalnya: antara muka java / protokol iOS) antara ViewModel dan View kerana kita biasanya berkomunikasi melalui Pattern Design Observer.

MVP menggunakan Corak Delegasi kerana Delegasi Layer Penyampai memerintahkan kepada Lihat Layer, jadi ia perlu mengetahui sesuatu tentang Lihat walaupun ia hanya tandatangan antara muka / protokol. Fikirkan perbezaan di antara Pusat Pemberitahuan dan Delegate TableView. Pusat Pemberitahuan tidak memerlukan antara muka untuk membuat saluran komunikasi, tetapi TableView Delegates menggunakan protokol yang harus dilaksanakan oleh kelas.

Fikirkan logik persembahan penunjuk muatan. Dalam MVP, penyampai melakukan ViewProtocol.showLoadingIndicator. Di MVVM mungkin ada isLoading property dalam ViewModel. Lapisan View melalui mengikat data automatik mengesan apabila harta ini berubah dan menyegarkan dirinya. MVP lebih penting daripada MVVM kerana Penyampai memberikan pesanan.

MVVM lebih mengenai perubahan data daripada pesanan langsung, dan kami membuat persatuan antara perubahan data dan melihat kemas kini. Sekiranya menggunakan RxSwift dan paradigma pengaturcaraan reaktif yang berfungsi bersama-sama dengan MVVM, kami telah membuat kod ini walaupun kurang penting dan lebih deklaratif.

MVVM lebih mudah untuk diuji daripada MVP kerana MVVM menggunakan Corak Rekaan Pemerhati yang memindahkan data antara komponen dengan cara yang dipadam.
Oleh itu, kita boleh menguji hanya dengan melihat perubahan dalam data hanya dengan membandingkan dua objek dan bukannya mencemarkan kaedah panggilan untuk menguji komunikasi antara View dan Presenter.

PS: Saya melakukan beberapa kemas kini kepada artikel yang membuatnya bertambah banyak, jadi ia perlu dibahagikan kepada tiga bahagian. Anda boleh membaca bahagian tiga di sini.

Bahagian dua berakhir di sini. Semua maklum balas adalah dialu-alukan. Bahagian tiga akan bercakap mengenai VIPER, VIP, Pemrograman Reaktif, Perdagangan, Kekangan dan Kontekstual.

Terima kasih kerana membaca! Jika anda suka artikel ini, sila bertepuk tangan
jadi orang lain boleh membacanya juga :)