HandsAppMVP: arsitektur iOS untuk outsourcing pengembangan studio

gambar

Kode yang baik dimulai dengan arsitektur, dan aplikasi iOS tidak terkecuali. Ada banyak pola standar, tetapi tujuan artikel ini bukan untuk membicarakannya, tetapi tentang pengalaman mengadaptasi salah satunya dan mengembangkan pola Anda sendiri. Kami menyebut adaptasi ini HandsAppMVP.

gambar

Dalam pengembangan iOS, arsitektur utamanya menentukan organisasi kelas dan dependensi untuk satu ViewController tertentu. Namun, komponen utama bisa bukan hanya dia, tetapi hanya UIView. Pilihannya tergantung pada tugas tertentu.

Perbandingan arsitektur


Ada beberapa templat arsitektur standar untuk iOS: MVC, MVP, MVVM, VIPER (tautan ke deskripsi masing-masing dapat ditemukan di akhir artikel).

Memilih arsitektur untuk pengembangan, kami mengidentifikasi parameter utama yang harus sesuai dengan: kecepatan pengembangan, fleksibilitas, dan ambang masuk yang rendah. Selanjutnya, kami mulai membandingkan tiga arsitektur terkenal dengan parameter-parameter ini dalam pikiran (template komunitas MVC iOS telah lama terkubur karena ketidakpatuhan yang besar dengan tanggung jawab tunggal).

Untuk tim outsourcing, kecepatan pengembangan sangat penting. VIPER adalah arsitektur yang paling kompleks dan "lambat", pengembangan lebih cepat menggunakan MVP atau MVVM murni, karena mereka memiliki lebih sedikit komponen.

Fleksibilitas berarti penambahan atau penghapusan fungsionalitas yang tidak menyakitkan dalam aplikasi. Parameter ini sangat berkorelasi dengan kecepatan pengembangan di semua tahap umur aplikasi, kecuali untuk yang awal. Fleksibilitas juga terkait erat dengan kesederhanaan pengujian - pengujian otomatis memberi keyakinan pengembang bahwa ia tidak akan memecahkan apa pun, dan membantu menghindari bug. MVP klasik tidak tercakup oleh tes, terutama jika Anda tidak menggunakan antarmuka kelas yang dibahas di bawah ini. MVVM dari sudut pandang pengujian juga memiliki kinerja yang buruk, karena pengujian kode reaktif membutuhkan waktu lebih lama. VIPER sangat bagus untuk menulis tes karena menghormati prinsip tanggung jawab tunggal sebanyak mungkin dan kelas tergantung pada abstraksi.

Dan parameter terakhir yang kami pertimbangkan adalah ambang entri. Ini menunjukkan seberapa cepat pengembang baru (pertama-tama, jones) menembus ke dalam arsitektur. Di sini MVVM menggunakan perpustakaan reaktif pihak ketiga (RxSwift, PromiseKit, dll.) Mengambil tempat terakhir yang terhormat karena alasan yang jelas. VIPER juga merupakan arsitektur yang agak rumit karena banyaknya komponen. MVP memiliki ambang masuk terendah.

Setelah mempertimbangkan pro dan kontra, kami sampai pada kesimpulan bahwa kami membutuhkan sesuatu yang sederhana seperti MVP, dan sefleksibel VIPER. Maka lahirlah ide untuk membuat arsitektur sendiri berdasarkan pada mereka - HandsAppMVP.

Perluas MVP


Komponen utama arsitektur kami adalah Model, View, Presenter. Mereka melakukan fungsi yang sama seperti dalam MVP klasik sesuai dengan skema terkenal:

gambar
[Skema MVP klasik]

Di sini dan di bawah ini, setiap komponen interaksi (kotak biru) dalam diagram adalah kelas yang seumur hidupnya bertepatan dengan masa View. Panah padat menunjukkan kepemilikan objek lain, tautan kuat, dan panah putus-putus menunjukkan tautan lemah. Dengan referensi yang lemah, kami mencegah ketergantungan sirkuler dan kebocoran memori.

Antarmuka


Pertama, kami menambahkan antarmuka ViewInput dan ViewOutput ke skema klasik ini. Kami memperhitungkan prinsip kelima SOLID - prinsip inversi ketergantungan. Ini lebih cenderung bukan tambahan, tetapi penyempurnaan untuk MVP. Ketergantungan pada abstraksi membantu untuk menyingkirkan keterhubungan komponen yang ketat dan memungkinkan Anda untuk menulis tes secara normal. Skema dengan mempertimbangkan antarmuka terlihat seperti ini:

gambar
[Menambahkan antarmuka ViewInput dan ViewOutput] Kotak

kecil adalah antarmuka.

Pengembang yang penuh perhatian akan bertanya, di mana antarmuka untuk Model? Sekarang kita beralih ke mereka.

Bekerja dengan data


Model data dalam arsitektur seluler adalah konsep kolektif. Contoh standar: aplikasi mengetuk jaringan untuk berinteraksi dengan server, kemudian menyimpan data di CoreData untuk pekerjaan offline, menulis beberapa informasi sederhana ke UserDefaults dan menyimpan JWT di Keychain. Semua data ini yang sedang berinteraksi dengan membuat Model.

Kelas yang bertanggung jawab untuk berinteraksi dengan wadah data dari jenis tertentu, kami sebut layanan data. Untuk setiap kontainer (basis data jarak jauh, basis data lokal, UserDefaults, dll.), Kelas layanan ditambahkan ke HandsAppMVP yang berinteraksi dengan presenter. Sekarang Anda juga dapat menambahkan antarmuka input / output untuk setiap layanan data:

gambar
[Menambahkan layanan untuk bekerja dengan data]

Tidak setiap kelas layanan perlu terhubung ke presenter menggunakan antarmuka, seperti, misalnya, saat menggunakan Moya. Moya adalah perpustakaan jaringan open-source. Moya menyediakan kelas layanan siap pakai (MoyaProvider), dan saat menulis tes, kita tidak harus membuat objek tiruan yang menggantikan ApiProvider. Moya menyediakan mode uji khusus, ketika dinyalakan, MoyaProvider tidak mengetuk jaringan, tetapi mengembalikan data pengujian (detail lebih lanjut dapat ditemukan di sini). Dalam hal ini, presenter tidak merujuk pada abstraksi MoyaProvider, tetapi pada implementasinya. Dan kami mendapatkan umpan balik dari layanan ini menggunakan penutupan. Contoh implementasi dapat ditemukan di proyek demo.

Contoh ini lebih merupakan pengecualian daripada aturan, dan menunjukkan bahwa kepatuhan terhadap SOLID tidak selalu merupakan solusi terbaik.

Navigasi


Kami menganggap navigasi dalam aplikasi sebagai tanggung jawab terpisah. HandsAppMVP menggunakan kelas khusus untuk itu - Router. Perute berisi tautan yang lemah ke tampilan, yang dengannya ia dapat menampilkan layar baru atau menutup yang sekarang. Router juga berinteraksi dengan presenter menggunakan antarmuka RouterInput:

gambar
[Menambahkan komponen untuk navigasi (Router)]

Perakitan komponen


Penambahan terakhir ke MVP klasik yang kami gunakan adalah Assembly, kelas kolektor. Ini digunakan untuk menginisialisasi View dan komponen lain dari HandsAppMVP, serta untuk mengimplementasikan dependensi. Assembly berisi satu-satunya metode publik - `assemble () -> UIViewController`, yang hasilnya adalah UIViewController yang diinginkan (atau UIView) dengan grafik ketergantungan yang diperlukan.

Kami tidak akan menampilkan Majelis pada diagram arsitektur, karena tidak terhubung dengan komponen MVP dan siklus masa pakainya berakhir segera setelah dibuat.

Pembuatan Kode


Untuk menghemat waktu, kami mengotomatiskan proses membuat kelas HandsAppMVP menggunakan Generamba. Templat yang digunakan untuk Generamba dapat ditemukan di repositori kami. Contoh konfigurasi untuk Generamba ada di proyek demo.

Sebagai hasil dari menghasilkan layar tertentu, kami mendapatkan satu set kelas yang cocok dengan skema HandsAppMVP, serangkaian tes unit untuk membuat dan mengimplementasikan komponen, dan kelas template untuk tes presenter.

Apa yang terjadi


Jika Anda membandingkan HeadApp to HeadAppAppVVP dan VIPER, Anda akan melihat bahwa mereka sangat mirip dan yang pertama hanya berbeda dalam ketiadaan komponen Interactor. Tetapi, dengan menghilangkan lapisan antara layanan dan saat ini (penghubung), serta menyederhanakan interaksi dengan jaringan menggunakan Moya, kami menerima peningkatan nyata dalam kecepatan pengembangan.

Kami menyarankan Anda untuk memperhatikan arsitektur pada tahap desain untuk menghindari kesalahan global, perselisihan dengan pelanggan dan siksaan pengembang di masa depan, dan alih-alih memimpin proses pengembangan secara kompeten dan dapat diprediksi.

Ingatlah bahwa arsitektur apa pun mungkin tidak cocok secara khusus untuk proyek Anda, jadi jangan buru-buru berpegang teguh pada templat yang sudah jadi dan kisah sukses aplikasi mereka. Jangan takut untuk mengembangkan dan menerapkan solusi Anda - mereka bisa menjadi lebih berharga dan fleksibel untuk Anda daripada yang sudah jadi.

Sebagai kesimpulan, kami akan merekomendasikan beberapa artikel bagus tentang arsitektur aplikasi iOS yang membantu kami memahami seluk-beluk dan membuat pilihan:

  1. Pola arsitektur di iOS
  2. iOS Swift: Arsitektur MVP
  3. Analisis arsitektur VIPER pada contoh aplikasi iOS kecil di Swift 4
  4. Menerapkan MVVM di iOS dengan RxSwift

Dokumentasi open-source SurfStudio juga sangat membantu dan terinspirasi .

Akhirnya, kami menempatkan tautan pada proyek DEMO , yang ditulis dalam HandsAppMVP, yang telah berulang kali kami sebutkan di artikel tersebut.

All Articles