Cara memilih Arsitektur iOS yang sesuai (Bagian 2)

MVC, MVP, MVVM, VIPER, atau VIP

Anda dapat berkonsultasi dengan bagian satu di sini.

Arsitektur iOS Utama

Tinjauan singkat.

MVC

Lapisan MVC adalah sebagai berikut:

M: Logika Bisnis, Lapisan Jaringan dan Lapisan Akses Data

V: Lapisan UI (hal-hal UIKit, Storyboards, Xibs)

C: Mediasi yang terkoordinasi antara Model dan Tampilan.

Untuk memahami MVC kita harus memahami konteks di mana ia diciptakan. MVC diciptakan pada masa pengembangan Web lama, di mana Views tidak memiliki status. Di masa lalu setiap kali kita membutuhkan perubahan visual di situs web, browser memuat ulang seluruh HTML lagi. Pada saat itu tidak ada konsep kondisi tampilan yang dipertahankan dan disimpan.

Misalnya, ada beberapa pengembang yang bercampur dalam file HTML, PHP, dan akses basis data yang sama. Jadi motivasi utama MVC adalah untuk memisahkan layer View dari layer Model. Ini meningkatkan testability dari lapisan Model. Seharusnya dalam MVC, layer View dan Model tidak tahu apa-apa tentang satu sama lain. Untuk membuat ini menjadi mungkin, lapisan perantara bernama Pengendali diciptakan. Ini adalah SRP yang diterapkan.

Contoh dari siklus MVC:

  1. Tindakan / peristiwa pengguna di Lapisan Tampilan (mis: Refresh Action) diluncurkan dan tindakan tersebut dikomunikasikan ke Controller
  2. Pengontrol yang meminta data ke Model Layer
  3. Modelkan data yang dikembalikan ke Controller
  4. Controller mengatakan untuk View memperbarui statusnya dengan Data baru
  5. Lihat perbarui keadaannya

Apple MVC

Di iOS, View Controller digabungkan ke UIKit dan tampilan siklus hidup, jadi itu bukan MVC murni. Namun, dalam definisi MVC, tidak ada yang mengatakan bahwa Pengendali tidak dapat mengetahui implementasi khusus Lihat atau Model. Tujuan utamanya adalah untuk memisahkan tanggung jawab lapisan Model dari lapisan Tampilan sehingga kita dapat menggunakannya kembali dan menguji lapisan Model secara terpisah.

ViewController berisi View dan memiliki Model. Masalahnya adalah kita biasa menulis kode pengontrol serta kode tampilan di ViewController.

MVC sering menciptakan masalah yang disebut Massive View Controller, tetapi itu hanya terjadi dan menjadi hal yang serius di aplikasi dengan kompleksitas yang cukup.

Ada beberapa metode yang dapat digunakan pengembang untuk membuat View Controller lebih mudah dikelola. Beberapa contoh:

  • Mengekstrak logika VC untuk kelas lain seperti metode tampilan tabel sumber data dan mendelegasikan untuk file lain menggunakan pola desain delegasi.
  • Buat pemisahan tanggung jawab yang lebih jelas dengan komposisi (mis. Pisahkan VC menjadi pengontrol tampilan anak).
  • Gunakan pola desain koordinator untuk menghilangkan tanggung jawab mengimplementasikan logika navigasi di VC
  • Gunakan kelas pembungkus DataPresenter yang merangkum logika dan mengubah model data menjadi output data yang mewakili data yang disajikan kepada pengguna akhir.

MVC vs MVP

Bagaimana Anda bisa melihat diagram MVP sangat mirip dengan MVC

MVC adalah langkah maju, tetapi masih ditandai dengan tidak adanya atau keheningan tentang beberapa hal.

Sementara itu, World Wide Web tumbuh dan banyak hal dalam komunitas pengembang berkembang. Sebagai contoh, para pemrogram mulai menggunakan Ajax dan hanya memuat sebagian halaman alih-alih seluruh halaman HTML sekaligus.

Dalam MVC saya pikir tidak ada yang menunjukkan bahwa Controller tidak boleh tahu implementasi spesifik View (absen).

HTML adalah bagian dari layer View dan banyak kasus bodoh sebagai bercinta. Dalam beberapa kasus, hanya menerima peristiwa dari pengguna dan menampilkan konten visual GUI.

Sebagai bagian dari halaman web mulai dimuat ke dalam bagian-bagian, segmentasi ini mengarah ke arah mempertahankan kondisi Lihat dan kebutuhan yang lebih besar untuk pemisahan tanggung jawab logika presentasi.

Logika presentasi adalah logika yang mengontrol bagaimana UI harus ditampilkan dan bagaimana elemen UI berinteraksi bersama. Contohnya adalah logika kontrol ketika Indikator memuat harus mulai menunjukkan / menghidupkan dan kapan harus berhenti menampilkan / menghidupkan.

Dalam MVP dan MVVM, View Layer harusnya bodoh tanpa adanya logika atau kecerdasan di dalamnya, dan di iOS, View Controller harus menjadi bagian dari View Layer. Fakta dari View dumb berarti bahwa bahkan logika presentasi tetap keluar dari layer View.

Salah satu masalah MVC adalah tidak jelas tentang di mana logika presentasi harus tetap. Dia hanya diam tentang itu. Haruskah logika presentasi berada di lapisan Lihat atau di Lapisan Model?

Jika peran Model adalah hanya menyediakan data "mentah", itu berarti bahwa kode dalam Tampilan adalah:

Pertimbangkan contoh berikut: kami memiliki Pengguna, dengan nama depan dan nama belakang. Dalam Tampilan, kita perlu menampilkan nama pengguna sebagai "Nama Belakang, Nama Depan" (mis. "Flores, Tiago").

Jika peran Model adalah untuk menyediakan data "mentah", itu berarti bahwa kode dalam Tampilan adalah:

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

Jadi ini berarti bahwa itu akan menjadi tanggung jawab View untuk menangani logika UI. Tapi ini membuat logika UI tidak mungkin untuk unit test.

Pendekatan lainnya adalah membuat Model mengekspos hanya data yang perlu ditampilkan, menyembunyikan logika bisnis apa pun dari View. Tapi kemudian, kita berakhir dengan Model yang menangani logika bisnis dan UI. Ini akan menjadi unit yang dapat diuji, tetapi kemudian Model berakhir, secara implisit tergantung pada View.

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

MVP jelas tentang itu dan logika presentasi tetap di Lapisan Presenter. Ini meningkatkan testability dari layer Presenter. Sekarang Model dan Presenter Layer mudah diuji.

Biasanya dalam implementasi MVP, View disembunyikan di belakang antarmuka / protokol dan seharusnya tidak ada referensi ke UIKit di Presenter.

Hal lain yang perlu diingat adalah dependensi transitif.

Jika Pengendali memiliki Lapisan Bisnis sebagai ketergantungan dan Lapisan Bisnis memiliki Lapisan Akses Data sebagai ketergantungan, maka Pengontrol memiliki ketergantungan transitif untuk Lapisan Akses Data. Karena implementasi MVP biasanya menggunakan kontrak (protokol) antara semua lapisan, ia tidak memiliki dependensi transitif.

Lapisan yang berbeda juga berubah karena alasan yang berbeda dan pada tingkat yang berbeda. Jadi, ketika Anda mengubah lapisan Anda tidak ingin ini menyebabkan efek sekunder / masalah di lapisan lain.

Protokol lebih stabil daripada kelas. Protokol belum detail implementasi dan dengan kontrak, sehingga dimungkinkan untuk mengubah detail implementasi layer tanpa mempengaruhi lapisan lainnya.

Jadi kontrak (protokol) membuat decoupling antar lapisan.

MVP vs MVVM

Diagram MVVM

Salah satu perbedaan utama antara MVP dan MVVM adalah bahwa dalam MVP Presenter berkomunikasi dengan antarmuka melalui tampilan, dan dalam MVVM, View berorientasi pada perubahan data dan peristiwa.

Di MVP kami membuat pengikatan manual antara Presenter dan View menggunakan Antarmuka / Protokol.
Dalam MVVM kami membuat pengikatan data otomatis menggunakan sesuatu seperti RxSwift, KVO atau menggunakan mekanisme dengan obat generik dan penutup.

Dalam MVVM kita bahkan tidak memerlukan kontrak (mis: antarmuka java / protokol iOS) antara ViewModel dan View karena kita biasanya berkomunikasi melalui Pola Desain Pengamat.

MVP menggunakan Pola Delegasi karena Presenter Layer Delegates memesan ke View Layer, jadi ia perlu mengetahui sesuatu tentang View walaupun itu hanya tanda tangan antarmuka / protokol. Pikirkan perbedaan antara Notification Center dan TableView Delegates. Notification Center tidak memerlukan antarmuka untuk membuat saluran komunikasi, tetapi TableView Delegates menggunakan protokol yang harus diimplementasikan oleh kelas.

Pikirkan logika presentasi dari indikator pemuatan. Dalam MVP presenter melakukan ViewProtocol.showLoadingIndicator. Di MVVM mungkin ada properti isLoading di ViewModel. Lapisan View melalui ikatan data otomatis mendeteksi ketika properti ini berubah dan menyegarkan dengan sendirinya. MVP lebih penting daripada MVVM karena Presenter memberi perintah.

MVVM lebih tentang perubahan data daripada pesanan langsung, dan kami membuat hubungan antara perubahan data dan melihat pembaruan. Jika menggunakan RxSwift dan paradigma pemrograman reaktif fungsional bersama-sama dengan MVVM, kami telah membuat kode tersebut menjadi lebih tidak penting dan lebih bersifat deklaratif.

MVVM lebih mudah untuk diuji daripada MVP karena MVVM menggunakan Pola Desain Pengamat yang mentransfer data antar komponen dengan cara dipisahkan.
Jadi kita bisa menguji hanya dengan melihat perubahan data hanya dengan membandingkan dua objek daripada membuat tiruan metode panggilan untuk menguji komunikasi antara View dan Presenter.

PS: Saya melakukan beberapa pembaruan pada artikel yang membuatnya bertambah banyak, jadi perlu membaginya menjadi tiga bagian. Anda dapat membaca bagian tiga di sini.

Bagian dua berakhir di sini. Semua umpan balik diterima. Bagian tiga akan berbicara tentang VIPER, VIP, Pemrograman Reaktif, Pengorbanan, Kendala dan Rasa Kontekstual.

Terima kasih telah membaca! Jika Anda menyukai artikel ini, silakan bertepuk tangan
jadi orang lain juga bisa membacanya :)