Back home

Pola Arsitektur iOS

Pola arsitektur iOS

##Pola Arsitektur iOS Pola arsitektur iOS

Mengungkap MVC, MVP, MVVM dan VIPER Mengungkap MVC, MVP, MVVM dan VIPER

Jangan lewatkan Peta Jalan Pengembang iOS untuk tahun 2018!

UPD: Slide yang saya presentasikan di NSLondon tersedia di sini. UPD: Slide yang saya presentasikan di NSLondon dapat ditemukan di sini.

Merasa aneh saat melakukan MVC di iOS? Ada keraguan untuk beralih ke MVVM? Pernah mendengar tentang VIPER, tapi tidak yakin apakah itu sepadan? Merasa aneh menggunakan MVC di iOS? Ada pertanyaan tentang beralih ke MVVM? Pernah mendengar tentang Viper, tapi tidak yakin apakah itu sepadan?

Teruslah membaca, dan Anda akan menemukan jawaban atas pertanyaan di atas, jika Anda tidak ragu untuk mengeluh di komentar. Baca terus dan Anda akan menemukan jawaban atas pertanyaan di atas, dan jika tidak – silakan mengeluh di komentar.

Anda akan menyusun pengetahuan Anda tentang pola arsitektur di lingkungan iOS. Kami akan meninjau secara singkat beberapa yang populer dan membandingkannya dalam teori dan praktik dengan memberikan beberapa contoh kecil. Ikuti tautan jika Anda memerlukan detail lebih lanjut tentang tautan tertentu. Anda akan membangun pengetahuan Anda tentang pola arsitektur di lingkungan iOS. Kami akan meninjau secara singkat beberapa contoh populer dan membandingkannya dalam teori dan praktik. Jika Anda memerlukan informasi terperinci tentang siapa pun, silakan ikuti tautannya.

Menguasai pola desain mungkin membuat ketagihan, jadi berhati-hatilah: Anda mungkin akan bertanya pada diri sendiri lebih banyak pertanyaan sekarang dibandingkan sebelum membaca artikel ini, seperti ini: Menguasai pola desain bisa membuat ketagihan, jadi berhati-hatilah: Anda mungkin bertanya pada diri sendiri lebih banyak pertanyaan sekarang dibandingkan sebelum membaca artikel ini, seperti:

Siapa yang seharusnya memiliki permintaan jaringan: Model atau Pengendali? Siapa yang harus memiliki permintaan jaringan: model atau pengontrol?

Bagaimana cara meneruskan Model ke Model Tampilan dari Tampilan baru? Bagaimana cara meneruskan model ke model tampilan tampilan baru?

Siapa yang membuat modul VIPER baru: Router atau Presenter? Siapa yang membuat modul Viper baru: router atau program demo?

Mengapa harus peduli dalam memilih arsitektur?

Mengapa Anda harus peduli dalam memilih arsitektur?

Karena jika suatu hari Anda tidak melakukan debug pada kelas besar yang berisi lusinan hal berbeda, Anda tidak akan dapat menemukan dan memperbaiki bug apa pun di kelas Anda. Tentu saja, sulit untuk mengingat kelas ini sebagai satu kesatuan, oleh karena itu, Anda akan selalu kehilangan beberapa detail penting. Jika Anda sudah mengalami situasi ini dengan lamaran Anda, kemungkinan besar: Karena jika Anda tidak melakukan ini, suatu hari, ketika men-debug kelas besar dengan banyak hal berbeda, Anda tidak akan dapat menemukan dan memperbaiki bug apa pun di kelas tersebut. “Tentu saja, sulit untuk mengingat kelas secara keseluruhan, jadi Anda selalu melewatkan beberapa detail penting. Jika lamaran Anda sudah berada dalam situasi ini, kemungkinan besar:

  • Kelas ini adalah subkelas UIViewController. Kelas ini adalah subkelas UIViewController.

  • Data Anda disimpan langsung di UIViewController Data Anda disimpan langsung di UIViewController

  • UIView Anda hampir tidak melakukan apa pun Uiview Anda hampir tidak melakukan apa pun

  • Model adalah struktur data yang bodoh Modelnya adalah struktur data yang bodoh

  • Tes Unit Anda tidak mencakup apa pun Tes unit Anda tidak mencakup apa pun

Dan ini bisa terjadi, meskipun Anda mengikuti pedoman Apple dan menerapkan pola MVC Apple, jadi jangan merasa bersalah. Ada yang salah dengan MVC Apple, tapi kita akan membahasnya lagi nanti. Hal ini dapat terjadi meskipun Anda mengikuti pedoman Apple dan menerapkan pola MVC Apple, jadi jangan merasa bersalah. MVC Apple memiliki beberapa masalah, tapi kami akan membahasnya lagi nanti.

Mari kita definisikan ciri-ciri arsitektur yang baik: Mari kita definisikan ciri-ciri arsitektur yang baik:

  1. Pembagian tanggung jawab yang seimbang antar entitas dengan peran yang ketat. Distribusi tanggung jawab yang seimbang antar entitas dengan peran yang ketat.

  2. Testabilitas biasanya berasal dari fitur pertama (dan jangan khawatir: mudah dilakukan dengan arsitektur yang sesuai). Testabilitas biasanya berasal dari fitur pertama (jangan khawatir: mudah dengan arsitektur yang sesuai).

  3. Kemudahan penggunaan dan biaya perawatan yang rendah. Mudah digunakan dan biaya perawatan rendah.

Mengapa Distribusi?

Mengapa didistribusikan?

Distribusi memberi beban yang cukup pada otak kita saat kita mencoba mencari tahu bagaimana segala sesuatunya bekerja. Jika Anda berpikir semakin Anda berkembang semakin baik otak Anda beradaptasi dalam memahami kompleksitas, maka Anda benar. Namun kemampuan ini tidak berskala linier dan mencapai batasnya dengan sangat cepat. Jadi cara termudah untuk mengatasi kompleksitas adalah dengan membagi tanggung jawab di antara beberapa entitas dengan mengikuti prinsip tanggung jawab tunggal. Distribusi memberikan beban yang cukup besar pada otak kita ketika kita mencoba mencari tahu bagaimana segala sesuatunya bekerja. Jika Anda berpikir bahwa semakin Anda berkembang, semakin baik otak Anda beradaptasi dalam memahami kompleksitas, Anda benar. Namun kemampuan ini tidak tumbuh secara linier dan akan dengan cepat mencapai batas atas. Oleh karena itu, cara paling sederhana untuk mengatasi kompleksitas adalah dengan membagi tanggung jawab di antara beberapa entitas dengan mengikuti prinsip tanggung jawab tunggal.

Mengapa Testabilitas?

Alasan testabilitas?

Ini biasanya bukan pertanyaan bagi mereka yang sudah merasa bersyukur dengan pengujian unit, yang gagal setelah menambahkan fitur baru atau karena memfaktorkan ulang beberapa seluk-beluk kelas. Artinya, pengujian ini menyelamatkan pengembang tersebut dari menemukan masalah saat runtime, yang mungkin terjadi saat aplikasi ada di perangkat pengguna dan perbaikan memerlukan waktu seminggu untuk sampai ke pengguna. Hal ini biasanya tidak menjadi masalah bagi mereka yang sudah bersyukur dengan pengujian unit yang gagal setelah fitur baru ditambahkan, atau karena beberapa kerumitan kelas difaktorkan ulang. Artinya, pengujian ini memungkinkan pengembang menghindari penemuan masalah saat runtime, yang dapat terjadi saat aplikasi berada di perangkat pengguna dan perbaikan memerlukan waktu seminggu untuk sampai ke pengguna.

Mengapa Kemudahan penggunaan?

Mengapa kemudahan penggunaan?Ini tidak memerlukan jawaban tetapi perlu disebutkan bahwa kode terbaik adalah kode yang belum pernah ditulis. Oleh karena itu, semakin sedikit kode yang Anda miliki, semakin sedikit bug yang Anda miliki. Artinya, keinginan untuk menulis lebih sedikit kode tidak boleh disebabkan oleh kemalasan pengembang saja, dan Anda tidak boleh memilih solusi cerdas yang menutup mata terhadap biaya pemeliharaannya. Ini tidak memerlukan jawaban, namun perlu disebutkan bahwa kode terbaik adalah kode yang belum pernah ditulis. Oleh karena itu, lebih sedikit kode berarti lebih sedikit bug. Ini berarti bahwa keinginan untuk menulis lebih sedikit kode tidak boleh disebabkan hanya oleh kemalasan pengembang, dan Anda tidak boleh menutup mata terhadap biaya pemeliharaan demi solusi yang lebih cerdas.

MV(X) penting

Kebutuhan MV (X)

Saat ini kami memiliki banyak pilihan dalam hal pola desain arsitektur: Sekarang, ketika berbicara tentang pola desain arsitektur, kita memiliki banyak pilihan:

*MVC *MVP *MVVM *VIPER

Tiga yang pertama mengasumsikan menempatkan entitas aplikasi ke dalam salah satu dari 3 kategori: Tiga asumsi pertama adalah membagi entitas aplikasi menjadi tiga kategori:

  • Model — Bertanggung jawab atas data domain atau lapisan akses data yang memanipulasi data, pikirkan kelas ‘Person’ atau ‘PersonDataProvider’. Model - Lapisan akses data yang bertanggung jawab atas data domain atau data operasional, pertimbangkan kelas “Person” atau “PersonDataProvider”.

  • Tampilan — Bertanggung jawab atas lapisan presentasi (GUI), untuk lingkungan iOS, pikirkan segala sesuatu yang dimulai dengan awalan ‘UI’. Lihat - Bertanggung jawab atas lapisan presentasi (GUI), untuk lingkungan iOS, pertimbangkan semuanya dimulai dengan “UI”.

  • Controller/Presenter/ViewModel - perekat atau mediator antara Model dan View, secara umum bertanggung jawab untuk mengubah Model dengan bereaksi terhadap tindakan pengguna yang dilakukan pada View dan memperbarui View dengan perubahan dari Model. Controller/Presenter/ViewModel—Perekat atau perantara antara model dan tampilan, biasanya bertanggung jawab untuk mengubah model sebagai respons terhadap tindakan pengguna pada tampilan dan memperbarui tampilan dengan perubahan dari model.

Membagi entitas memungkinkan kita untuk: Pemisahan entitas memungkinkan kita untuk:

  • memahaminya dengan lebih baik (seperti yang sudah kita ketahui) Pahami mereka dengan lebih baik (seperti yang sudah kita ketahui)

  • menggunakannya kembali (kebanyakan berlaku untuk Tampilan dan Model) Gunakan kembali (terutama berlaku untuk tampilan dan model)

  • mengujinya secara mandiri pengujian independen

Mari kita mulai dengan pola MV(X) dan kembali ke VIPER nanti. Mari kita mulai dengan mode MV(X) dan kembali ke VIPER nanti.

###MVC

Bagaimana dulu

bagaimana keadaannya di masa lalu

Sebelum membahas visi Apple tentang MVC, mari kita lihat yang tradisional. Sebelum membahas visi MVC Apple, mari kita lihat MVC tradisional. MVC Tradisional

Dalam hal ini, View tidak memiliki kewarganegaraan. Ini hanya dirender oleh Controller setelah Model diubah. Bayangkan halaman web dimuat ulang sepenuhnya setelah Anda menekan tautan untuk bernavigasi di tempat lain. Meskipun dimungkinkan untuk mengimplementasikan MVC tradisional di aplikasi iOS, hal ini tidak masuk akal karena masalah arsitekturalnya — ketiga entitas tersebut digabungkan secara erat, masing-masing entitas tahu tentang dua entitas lainnya. Hal ini secara drastis mengurangi kemampuan penggunaan kembali masing-masingnya—hal ini bukanlah hal yang ingin Anda miliki dalam aplikasi Anda. Karena alasan ini, kami bahkan melewatkan upaya menulis contoh MVC kanonik. Dalam hal ini, tampilannya tidak memiliki kewarganegaraan. Setelah model diubah, pengontrol akan merendernya. Saat Anda menekan tautan untuk bernavigasi ke tempat lain, pertimbangkan untuk memuat ulang seluruh halaman web. Meskipun dimungkinkan untuk mengimplementasikan MVC tradisional di aplikasi iOS, hal ini tidak masuk akal karena masalah arsitektural - ketiga entitas tersebut digabungkan secara erat, dan masing-masing entitas mengetahui dua entitas lainnya. Hal ini sangat mengurangi kegunaannya kembali - bukan sesuatu yang Anda ingin miliki dalam aplikasi Anda. Karena alasan ini, kami bahkan melewatkan penulisan contoh MVC kanonik.

MVC tradisional tampaknya tidak berlaku untuk pengembangan iOS modern. MVC tradisional tampaknya tidak berfungsi untuk pengembangan iOS modern.

MVC Apple

Apple MVC

Harapan

Harapan

KakaoMVC

Controller merupakan mediator antara View dan Model sehingga keduanya tidak saling mengetahui satu sama lain. Yang paling tidak dapat digunakan kembali adalah Controller dan ini biasanya baik-baik saja bagi kita, karena kita harus memiliki tempat untuk semua logika bisnis rumit yang tidak sesuai dengan Model. Controller merupakan perantara antara view dan model, sehingga keduanya tidak saling mengetahui satu sama lain. Hal yang paling sedikit dapat digunakan kembali adalah pengontrol, yang biasanya tidak menjadi masalah bagi kami karena kami harus menyediakan tempat untuk semua logika bisnis kompleks yang tidak sesuai dengan model.

Secara teori memang terlihat sangat mudah, namun Anda merasa ada yang tidak beres bukan? Anda bahkan mendengar orang menyingkat MVC sebagai Pengontrol Tampilan Besar. Selain itu, pembongkaran pengontrol tampilan menjadi topik penting bagi pengembang iOS. Mengapa ini terjadi jika Apple hanya menggunakan MVC tradisional dan memperbaikinya sedikit? Secara teori, ini tampak sederhana, tetapi Anda merasa ada yang tidak beres, bukan? Anda bahkan pernah mendengar orang menyingkat MVC menjadi Large View Controller. Selain itu, pembongkaran pengontrol tampilan telah menjadi topik penting bagi pengembang iOS. Mengapa hal ini terjadi jika Apple hanya menggunakan MVC tradisional dan melakukan beberapa perbaikan?

MVC Apple

Apple MVC

Kenyataan

kenyataan

MVC Kakao RealistisCocoa MVC mendorong Anda untuk menulis Massive View Controllers, karena mereka sangat terlibat dalam siklus hidup View sehingga sulit untuk mengatakan bahwa mereka terpisah. Meskipun Anda masih memiliki kemampuan untuk memindahkan beberapa logika bisnis dan transformasi data ke Model, Anda tidak punya banyak pilihan ketika harus memindahkan pekerjaan ke View, seringkali tanggung jawab View adalah mengirimkan tindakan ke Controller. Pengontrol tampilan akhirnya menjadi delegasi dan sumber data dari segalanya, dan biasanya bertanggung jawab untuk mengirimkan dan membatalkan permintaan jaringan dan… sebut saja. Cocoa MVC mendorong Anda untuk menulis pengontrol tampilan dalam jumlah besar, karena pengontrol tampilan tersebut sangat penting dalam siklus hidup tampilan sehingga sulit untuk mengatakan bahwa pengontrol tersebut independen. Meskipun Anda masih memiliki kemampuan untuk menjual beberapa logika bisnis dan transformasi data ke model, Anda tidak memiliki banyak pilihan ketika harus memindahkan pekerjaan ke tampilan; sebagian besar waktu, tanggung jawab tampilan adalah mengirimkan tindakan ke pengontrol. Pengontrol tampilan pada akhirnya adalah delegasi dan sumber data untuk semuanya, dan umumnya bertanggung jawab untuk mengirimkan dan membatalkan permintaan jaringan, dan… sebut saja.

Berapa kali Anda melihat kode seperti ini: Berapa kali Anda melihat kode seperti ini:

  
var userCell = tableView.dequeueReusableCellWithIdentifier("identifier") as UserCell
userCell.configureWithUser(user)

Sel yang merupakan Tampilan dikonfigurasi langsung dengan Model, sehingga pedoman MVC dilanggar, tetapi ini terjadi setiap saat, dan biasanya orang tidak merasa itu salah. Jika Anda benar-benar mengikuti MVC, maka Anda harus mengonfigurasi sel dari pengontrol, dan tidak meneruskan Model ke View, dan ini akan semakin meningkatkan ukuran Controller Anda. Sel adalah tampilan yang dikonfigurasi langsung dengan model, sehingga melanggar pedoman MVC, namun hal ini sering terjadi sehingga orang biasanya tidak merasa bahwa hal tersebut salah. Jika Anda benar-benar mengikuti MVC, Anda harus mengonfigurasi sel dari pengontrol alih-alih meneruskan model ke tampilan, yang selanjutnya akan meningkatkan ukuran pengontrol.

Cocoa MVC tidak disingkat sebagai Massive View Controller. Cocoa MVC cukup disederhanakan menjadi pengontrol tampilan besar.

Masalahnya mungkin tidak terlihat sampai pada Pengujian Unit (semoga saja terjadi di proyek Anda). Karena pengontrol tampilan Anda terkait erat dengan tampilan, pengujian menjadi sulit karena Anda harus sangat kreatif dalam meniru tampilan dan siklus hidupnya, sambil menulis kode pengontrol tampilan sedemikian rupa, sehingga logika bisnis Anda sebisa mungkin dipisahkan dari kode tata letak tampilan. Masalah ini mungkin tidak terlihat jelas sebelum pengujian unit (semoga ada di proyek Anda). Karena pengontrol tampilan Anda terkait erat dengan tampilan, maka sulit untuk mengujinya karena saat mengejek Anda harus sangat kreatif dengan tampilan dan siklus hidupnya, dan dalam menulis kode pengontrol tampilan sedemikian rupa sehingga logika bisnis Anda dipisahkan sebanyak mungkin dari kode tata letak tampilan.

Mari kita lihat contoh taman bermain sederhana: Mari kita lihat contoh taman bermain sederhana:

UPD: Lihat contoh kode yang diperbarui oleh Wasin Thonkaew UPD: Lihat contoh kode terbaru Wasin Thonkaew


import UIKit

struct Person { // Model
    let firstName: String
    let lastName: String
}

class GreetingViewController : UIViewController { // View + Controller
    var person: Person!
    let showGreetingButton = UIButton()
    let greetingLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.showGreetingButton.addTarget(self, action: "didTapButton:", forControlEvents: .TouchUpInside)
    }
    
    func didTapButton(button: UIButton) {
        let greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
        self.greetingLabel.text = greeting
        
    }
    // layout code goes here
}
// Assembling of MVC
let model = Person(firstName: "David", lastName: "Blaine")
let view = GreetingViewController()
view.person = model;

Contoh MVC

Perakitan MVC dapat dilakukan di pengontrol tampilan presentasi Perakitan MVC dapat dilakukan di pengontrol tampilan presentasi

Ini sepertinya tidak bisa diuji, bukan? Kita dapat memindahkan pembuatan salam ke dalam kelas GrenadeModel yang baru dan mengujinya secara terpisah, namun kita tidak dapat menguji logika presentasi apa pun (walaupun tidak banyak logika seperti itu dalam contoh di atas) di dalam GrenadeViewController tanpa memanggil metode terkait UIView secara langsung (viewDidLoad, didTapButton) yang mungkin menyebabkan memuat semua tampilan, dan ini buruk untuk pengujian unit. Ini sepertinya tidak mungkin dilakukan, bukan? Kita bisa mengganti Salam ke dalam kelas GrenadeModel yang baru dan mengujinya satu per satu, namun kita tidak akan bisa menguji logika presentasi apa pun (walaupun tidak banyak logika seperti itu dalam contoh di atas) di GrenadeViewController tanpa secara langsung memanggil metode terkait UIView (viewDidLoad didTapButton) yang mungkin menyebabkan semua tampilan dimuat, sehingga tidak kondusif untuk pengujian unit.

Faktanya, memuat dan menguji UIViews pada satu simulator (misalnya iPhone 4S) tidak menjamin bahwa itu akan berfungsi dengan baik pada perangkat lain (misalnya iPad), jadi saya sarankan untuk menghapus “Aplikasi Host” dari konfigurasi target Pengujian Unit Anda dan menjalankan pengujian Anda tanpa aplikasi Anda berjalan di simulator. Faktanya, memuat dan menguji UIView pada satu simulator (seperti iPhone 4S) tidak menjamin bahwa itu akan berfungsi dengan benar pada perangkat lain (seperti iPad), jadi saya sarankan menghapus “Aplikasi Host” dari konfigurasi target pengujian unit dan menjalankan pengujian dengan aplikasi yang berjalan pada simulator.

Interaksi antara Tampilan dan Pengontrol tidak dapat diuji dengan Pengujian Unit Interaksi antara tampilan dan pengontrol sebenarnya tidak dapat diuji melalui pengujian unit

Dengan semua yang dikatakan, tampaknya Cocoa MVC adalah pola yang buruk untuk dipilih. Namun mari kita menilainya berdasarkan fitur yang ditentukan di awal artikel: Singkatnya, memilih Cocoa MVC sepertinya merupakan model yang sangat buruk. Namun mari kita evaluasi dari ciri-ciri yang ditentukan di awal artikel:

  • **Distribusi **—Tampilan dan Model sebenarnya terpisah, namun Tampilan dan Pengontrol digabungkan erat. Distribusi - Tampilan dan model secara efektif terpisah, namun tampilan dan pengontrol digabungkan secara erat.

  • Testabilitas — karena distribusi yang buruk, Anda mungkin hanya akan menguji Model Anda. Testabilitas - Anda hanya dapat menguji model Anda karena distribusi yang buruk.

  • Kemudahan penggunaan — jumlah kode paling sedikit di antara pola lainnya. Selain itu, semua orang sudah mengenalnya, sehingga mudah dikelola bahkan oleh pengembang yang tidak berpengalaman. Kemudahan penggunaan - Jumlah kode minimal di antara mode lainnya. Selain itu, semua orang sudah mengenalnya, sehingga pemeliharaannya mudah bahkan bagi pengembang yang tidak berpengalaman.Cocoa MVC adalah pola pilihan Anda jika Anda tidak siap untuk menginvestasikan lebih banyak waktu dalam arsitektur Anda, dan Anda merasa bahwa sesuatu dengan biaya pemeliharaan yang lebih tinggi adalah hal yang berlebihan untuk proyek kecil kesayangan Anda. Jika Anda belum siap untuk menginvestasikan lebih banyak waktu dalam arsitektur dan Anda merasa bahwa sesuatu dengan biaya pemeliharaan yang lebih tinggi tidak berguna untuk proyek kecil Anda, maka Anda dapat memilih pola Cocoa MVC.

Cocoa MVC adalah pola arsitektur terbaik dalam hal kecepatan pengembangan. Dalam hal kecepatan pengembangan, Cocoa MVC adalah pola arsitektur terbaik.

###MVP

Janji Cocoa MVC terealisasi

Janji Kakao MVC telah terealisasi

Varian Tampilan Pasif dari MVP

Bukankah ini persis seperti MVC Apple? Ya, benar, dan namanya adalah MVP (varian Tampilan Pasif). Tapi tunggu dulu… Apakah ini berarti MVC Apple sebenarnya adalah MVP? Tidak, tidak, karena jika Anda ingat, di sana, View digabungkan erat dengan Controller, sedangkan mediator MVP, Presenter, tidak ada hubungannya dengan siklus hidup pengontrol tampilan, dan View dapat ditiru dengan mudah, jadi tidak ada kode tata letak di Presenter sama sekali, tetapi bertanggung jawab untuk memperbarui View dengan data dan status. Bukankah ini terlihat seperti MVC Apple? Ya benar, dan namanya MVP (Passive View Variant). Tapi tunggu dulu, apakah ini berarti MVC Apple sebenarnya adalah MVP? Tidak, tidak, karena jika Anda ingat, di sana, tampilan terkait erat dengan pengontrol, dan mediator MVP, presenter, tidak ada hubungannya dengan siklus hidup pengontrol tampilan, tampilan dapat dengan mudah ditiru, sehingga tidak ada kode tata letak di presenter, tetapi bertanggung jawab untuk memperbarui tampilan dengan data dan status.

Bagaimana jika saya katakan, UIViewController adalah Tampilan. Jika saya memberi tahu Anda bahwa UIViewController adalah sebuah tampilan.

Dalam hal MVP, subkelas UIViewController sebenarnya adalah Views dan bukan Presenter. Perbedaan ini memberikan kemampuan pengujian yang luar biasa, yang mengorbankan kecepatan pengembangan, karena Anda harus membuat data manual dan pengikatan peristiwa, seperti yang dapat Anda lihat dari contoh: Sejauh menyangkut MVP, subkelas UIViewController sebenarnya adalah tampilan, bukan presenter. Perbedaan ini memberikan kemampuan pengujian yang sangat baik, namun hal ini mengorbankan kecepatan pengembangan karena Anda harus melakukan pengikatan data dan peristiwa secara manual, seperti yang dapat Anda lihat dari contoh:


import UIKit

struct Person { // Model
    let firstName: String
    let lastName: String
}

protocol GreetingView: class {
    func setGreeting(greeting: String)
}

protocol GreetingViewPresenter {
    init(view: GreetingView, person: Person)
    func showGreeting()
}

class GreetingPresenter : GreetingViewPresenter {
    unowned let view: GreetingView
    let person: Person
    required init(view: GreetingView, person: Person) {
        self.view = view
        self.person = person
    }
    func showGreeting() {
        let greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
        self.view.setGreeting(greeting)
    }
}

class GreetingViewController : UIViewController, GreetingView {
    var presenter: GreetingViewPresenter!
    let showGreetingButton = UIButton()
    let greetingLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.showGreetingButton.addTarget(self, action: "didTapButton:", forControlEvents: .TouchUpInside)
    }
    
    func didTapButton(button: UIButton) {
        self.presenter.showGreeting()
    }
    
    func setGreeting(greeting: String) {
        self.greetingLabel.text = greeting
    }
    
    // layout code goes here
}
// Assembling of MVP
let model = Person(firstName: "David", lastName: "Blaine")
let view = GreetingViewController()
let presenter = GreetingPresenter(view: view, person: model)
view.presenter = presenter

Contoh MVP

Catatan penting mengenai perakitan

Catatan penting tentang perakitan

MVP adalah pola pertama yang mengungkap masalah perakitan yang terjadi karena memiliki tiga lapisan yang sebenarnya terpisah. Karena kita tidak ingin View mengetahui tentang Model, maka tidak tepat melakukan perakitan dalam menghadirkan pengontrol tampilan (yang merupakan View), jadi kita harus melakukannya di tempat lain. Misalnya, kita dapat membuat layanan Router di seluruh aplikasi yang akan bertanggung jawab untuk melakukan perakitan dan presentasi View-to-View. Masalah ini muncul dan harus diatasi tidak hanya di MVP tetapi juga di semua pola berikut. MVP adalah pola pertama yang mengungkap masalah perakitan karena memiliki tiga lapisan yang benar-benar independen. Karena kita tidak ingin tampilan mengetahui modelnya, melakukan perakitan saat pengontrol tampilan (yaitu tampilan) disajikan adalah salah, jadi kita harus melakukannya di tempat lain. Misalnya, kita dapat membuat layanan router seluruh aplikasi yang akan bertanggung jawab untuk melakukan perakitan dan presentasi view-to-view. Masalah ini tidak hanya muncul di MVP, tetapi harus diselesaikan di semua pola berikut.

Mari kita lihat fitur MVP: Mari kita lihat ciri-ciri MVP:

  • Distribusi — kami memiliki sebagian besar tanggung jawab yang dibagi antara Presenter dan Model, dengan Tampilan yang cukup bodoh (dalam contoh di atas, Model juga bodoh). Distribusi - Kami membagi sebagian besar tanggung jawab antara presenter dan model, dan menggunakan pandangan yang cukup bodoh (dalam contoh di atas, modelnya juga bodoh).

  • Testabilitas—sangat bagus, kami dapat menguji sebagian besar logika bisnis karena Tampilan bodoh. Testabilitas - Sangat bagus, kami dapat menguji sebagian besar logika bisnis berkat pandangan bodoh.

  • Mudah digunakan— Dalam contoh sederhana yang tidak realistis, jumlah kode menjadi dua kali lipat dibandingkan dengan MVC, namun pada saat yang sama, gagasan MVP sangat jelas. Kemudahan penggunaan - Dalam contoh sederhana kami yang tidak realistis, jumlah kode menjadi dua kali lipat dibandingkan dengan MVC, namun pada saat yang sama, konsep MVP sangat jelas.

MVP di iOS berarti kemampuan pengujian yang luar biasa dan banyak kode. MVP di iOS berarti kemampuan pengujian yang hebat dan banyak kode.

###MVP pemain paling berharga

Dengan Binding dan Hooters

dengan tali dan topi

Ada jenis MVP lainnya—MVP Pengendali Pengawas. Varian ini mencakup pengikatan langsung View dan Model sementara Presenter (Pengontrol Pengawas) masih menangani tindakan dari View dan mampu mengubah View. Ada jenis lain dari MVP–MVP pemain pengawas. Varian ini mencakup pengikatan langsung antara tampilan dan model, sedangkan presenter (pengendali pemantauan) masih menangani operasi dari tampilan dan mampu mengubah tampilan.

Mengawasi varian Presenter dari MVP

Namun seperti yang telah kita pelajari sebelumnya, pemisahan tanggung jawab yang tidak jelas adalah hal yang buruk, begitu juga dengan penggabungan yang erat antara View dan Model. Hal ini mirip dengan cara kerja dalam pengembangan desktop Cocoa. Namun seperti yang telah kita pelajari sebelumnya, pemisahan tanggung jawab yang tidak jelas adalah hal yang buruk, begitu juga dengan penggabungan yang ketat antara pandangan dan model. Ini mirip dengan cara kerjanya dalam pengembangan desktop Cocoa.

Sama seperti MVC tradisional, saya tidak melihat ada gunanya menulis contoh arsitektur yang cacat. Seperti halnya MVC tradisional, menurut saya tidak perlu menulis contoh untuk arsitektur yang cacat.

###MVVM

Jenis MV(X) terbaru dan terhebat Kategori MV(X) Terbaru dan TerhebatMVVM adalah yang terbaru dari jenis MV(X), jadi semoga saja MVVM ini muncul dengan mempertimbangkan permasalahan yang dihadapi MV(X) sebelumnya. MVVM merupakan tipe MV(X) terbaru, jadi semoga saja ini keluar mengingat permasalahan yang dihadapi MV(X) sebelumnya.

Secara teori Model-View-ViewModel terlihat sangat bagus. View dan Model sudah tidak asing lagi bagi kita, tetapi juga Mediator, yang direpresentasikan sebagai View Model. Secara teori, model-view-viewmodel terlihat sangat bagus. Tampilan dan model sudah tidak asing lagi bagi kita, begitu pula mediasi, yang direpresentasikan sebagai model tampilan.

Ini sangat mirip dengan MVP: Ini sangat mirip dengan MVP:

  • MVVM memperlakukan pengontrol tampilan sebagai Tampilan MVVM memperlakukan pengontrol tampilan sebagai tampilan

  • Tidak ada ikatan erat antara Tampilan dan Model Tidak ada hubungan erat antara tampilan dan model

Selain itu, ia mengikat seperti versi Pengawasan dari MVP; namun, kali ini bukan antara View dan Model, namun antara View dan View Model. Selain itu, ini mengikat seperti versi regulasi MVP; Namun, kali ini bukan antara tampilan dan model, melainkan antara tampilan dan model tampilan.

Jadi apa yang dimaksud dengan Model Tampilan di realitas iOS? Ini pada dasarnya adalah representasi UIKit independen dari Tampilan Anda dan statusnya. View Model memanggil perubahan dalam Model dan mengupdate dirinya sendiri dengan Model yang telah diperbarui, dan karena kita memiliki ikatan antara View dan View Model, maka yang pertama akan diperbarui sesuai dengan itu. Apa yang dimaksud dengan model tampilan di iOS? Ini pada dasarnya adalah representasi independen UIKit atas suatu pandangan dan keadaannya. Model tampilan memanggil perubahan dalam model dan memperbarui dirinya sendiri dengan model yang diperbarui, dan karena kita memiliki ikatan antara tampilan dan model tampilan, model pertama akan diperbarui sesuai dengan itu.

Ikatan

mengikat

Saya menyebutkannya secara singkat di bagian MVP, tapi mari kita bahas sedikit di sini. Binding sudah tersedia untuk pengembangan OS X, namun kami tidak memilikinya di kotak peralatan iOS. Tentu saja kami memiliki KVO dan notifikasi, tetapi tidak senyaman binding. Saya menyebutkannya secara singkat di bagian MVP, tapi mari kita bahas di sini. Binding sudah tersedia untuk pengembangan OS X, tetapi kami tidak memilikinya di kotak peralatan iOS. Tentu saja, kami memiliki KVO dan notifikasi, tetapi tidak senyaman mengikat.

Jadi, asalkan kita tidak ingin menulisnya sendiri, kita punya dua pilihan: Jadi, jika kita tidak ingin menulisnya sendiri, kita punya dua pilihan:

  • Salah satu perpustakaan pengikatan berbasis KVO seperti RZDataBinding atau SwiftBond Salah satu perpustakaan pengikatan berbasis KVO seperti RZDataBinding atau SwiftBond

  • Binatang pemrograman reaktif fungsional skala penuh seperti ReactiveCocoa, RxSwift atau PromiseKit. Alat pemrograman reaktif berfitur lengkap seperti ReactiveCocoa, RxSwift, atau janji eKit.

Faktanya, saat ini, jika Anda mendengar “MVVM” — Anda akan berpikir ReactiveCocoa, dan sebaliknya. Meskipun dimungkinkan untuk membangun MVVM dengan binding sederhana, ReactiveCocoa (atau saudara kandungnya) akan memungkinkan Anda mendapatkan sebagian besar MVVM. Faktanya, saat ini, jika Anda mendengar “MVVM”, Anda pasti memikirkan ReactiveCocoa, dan sebaliknya. Meskipun dimungkinkan untuk membangun MVVM dengan binding sederhana, ReactiveCocoa (atau saudara kandungnya) akan memungkinkan Anda mendapatkan sebagian besar MVVM.

Ada satu kebenaran pahit tentang kerangka reaktif: kekuatan besar disertai dengan tanggung jawab yang besar. Sangat mudah untuk mengacaukan segalanya ketika Anda menjadi reaktif. Dengan kata lain, jika Anda melakukan kesalahan, Anda mungkin menghabiskan banyak waktu untuk men-debug aplikasi, jadi lihat saja tumpukan panggilan ini. Ada kebenaran yang menyakitkan tentang kerangka reaktif: Dengan kekuatan yang besar, ada pula tanggung jawab yang besar. Sangat mudah untuk membuat kesalahan ketika Anda bereaksi berlebihan. Dengan kata lain, jika Anda melakukan kesalahan, Anda mungkin menghabiskan banyak waktu untuk men-debug aplikasi Anda, jadi lihat saja tumpukan panggilan ini.

Debugging Reaktif

Dalam contoh sederhana kita, kerangka kerja FRF atau bahkan KVO berlebihan, sebagai gantinya kita akan secara eksplisit meminta Model Tampilan untuk memperbarui menggunakan metode showGreeting dan menggunakan properti sederhana untuk fungsi panggilan balik salamDidChange. Dalam contoh sederhana kita, kerangka FRF atau bahkan KVO adalah mubazir, sebagai gantinya kita akan secara eksplisit meminta model tampilan untuk memperbarui menggunakan metode showGreeting dan properti sederhana menggunakan fungsi callback salamDidChange.


import UIKit

struct Person { // Model
    let firstName: String
    let lastName: String
}

protocol GreetingViewModelProtocol: class {
    var greeting: String? { get }
    var greetingDidChange: ((GreetingViewModelProtocol) -> ())? { get set } // function to call when greeting did change
    init(person: Person)
    func showGreeting()
}

class GreetingViewModel : GreetingViewModelProtocol {
    let person: Person
    var greeting: String? {
        didSet {
            self.greetingDidChange?(self)
        }
    }
    var greetingDidChange: ((GreetingViewModelProtocol) -> ())?
    required init(person: Person) {
        self.person = person
    }
    func showGreeting() {
        self.greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
    }
}

class GreetingViewController : UIViewController {
    var viewModel: GreetingViewModelProtocol! {
        didSet {
            self.viewModel.greetingDidChange = { [unowned self] viewModel in
                self.greetingLabel.text = viewModel.greeting
            }
        }
    }
    let showGreetingButton = UIButton()
    let greetingLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.showGreetingButton.addTarget(self.viewModel, action: "showGreeting", forControlEvents: .TouchUpInside)
    }
    // layout code goes here
}
// Assembling of MVVM
let model = Person(firstName: "David", lastName: "Blaine")
let viewModel = GreetingViewModel(person: model)
let view = GreetingViewController()
view.viewModel = viewModel

Contoh MVVM

Dan sekali lagi kembali ke penilaian fitur kami: Kembali ke evaluasi fitur kami:

  • Distribusi — tidak jelas dalam contoh kecil kami, namun, pada kenyataannya, Tampilan MVVM memiliki tanggung jawab lebih besar daripada Tampilan MVP. Karena yang pertama memperbarui statusnya dari Model Tampilan dengan menyiapkan pengikatan, sedangkan yang kedua hanya meneruskan semua peristiwa ke Presenter dan tidak memperbarui dirinya sendiri. Distribusi - Tidak jelas dalam contoh kecil kita, namun kenyataannya, pandangan MVVM memiliki tanggung jawab lebih dari pandangan MVP. Karena yang pertama memperbarui status dalam model tampilan dengan mengatur pengikatan, sedangkan yang kedua hanya meneruskan semua peristiwa ke presenter tanpa memperbarui dirinya sendiri.

  • Testabilitas — Model Tampilan tidak mengetahui apa pun tentang Tampilan, sehingga memungkinkan kami mengujinya dengan mudah. Tampilan mungkin juga diuji, tetapi karena bergantung pada UIKit, Anda mungkin ingin melewatkannya. Testabilitas – Model tampilan tidak mengetahui apa pun tentang tampilan, sehingga memungkinkan kita mengujinya dengan mudah. Tampilan juga dapat diuji, tetapi karena bergantung pada UIKit, Anda mungkin ingin melewatkannya.

  • Mudah digunakan— memiliki jumlah kode yang sama dengan MVP dalam contoh kita, namun dalam aplikasi nyata di mana Anda harus meneruskan semua acara dari Tampilan ke Presenter dan memperbarui Tampilan secara manual, MVVM akan jauh lebih ramping jika Anda menggunakan binding. Mudah digunakan - ia memiliki jumlah kode yang sama dengan MVP dalam contoh kita, tetapi dalam aplikasi nyata Anda harus meneruskan semua acara dari tampilan ke presenter dan memperbarui tampilan secara manual, MVVM akan lebih tipis jika menggunakan binding.> MVVM sangat menarik, karena menggabungkan manfaat dari pendekatan yang disebutkan di atas, dan, selain itu, tidak memerlukan kode tambahan untuk pembaruan Tampilan karena pengikatan di sisi Tampilan. Meskipun demikian, testabilitasnya masih berada pada level yang baik. MVVM sangat menarik karena menggabungkan keunggulan metode di atas dan karena pengikatan pada sisi tampilan, tidak memerlukan kode tambahan untuk memperbarui tampilan. Meski begitu, testabilitasnya berada pada level yang baik.

ULAR

Pengalaman membangun LEGO ditransfer ke desain aplikasi iOS Pengalaman membangun LEGO ditransfer ke desain aplikasi iOS

VIPER adalah kandidat terakhir kami, yang menarik karena tidak berasal dari kategori MV(X). VIPER merupakan kandidat terakhir kami yang sangat menarik karena bukan dari kelas MV(X).

Saat ini, Anda pasti setuju bahwa perincian tanggung jawab sudah sangat baik. VIPER membuat iterasi lain mengenai gagasan pemisahan tanggung jawab, dan kali ini kami memiliki lima lapisan. Sekarang Anda harus setuju bahwa perincian tanggung jawabnya cukup bagus. VIPER mempunyai iterasi lain dari konsep pemisahan tanggung jawab, kali ini kami memiliki 5 lapisan.

VIPER

  • Interactor — berisi logika bisnis yang terkait dengan data (Entitas) atau jaringan, seperti membuat instance entitas baru atau mengambilnya dari server. Untuk tujuan tersebut Anda akan menggunakan beberapa Layanan dan Manajer yang tidak dianggap sebagai bagian dari modul VIPER melainkan ketergantungan eksternal. Interactor—Berisi logika bisnis yang terkait dengan data (entitas) atau jaringan, seperti membuat instance entitas baru atau mengambilnya dari server. Untuk tujuan ini Anda akan menggunakan beberapa layanan dan manajer yang tidak dianggap sebagai bagian dari modul VIPER tetapi merupakan ketergantungan eksternal.

  • Presenter berarti—berisi logika bisnis yang terkait dengan UI (tetapi independen dari UIKit), memanggil metode pada Interactor. Presenter - Berisi logika bisnis yang terkait dengan UI (tetapi tidak bergantung pada UIKit), memanggil metode pada interaksi.

  • Entitas berarti—objek data biasa Anda, bukan lapisan akses data, karena itu adalah tanggung jawab Interactor. Entitas - objek data normal Anda, bukan lapisan akses data karena itu adalah tanggung jawab interaksi.

  • Router—bertanggung jawab atas pemisahan antar modul VIPER. Router - Bertanggung jawab untuk pemisahan antar modul Viper.

Pada dasarnya, modul VIPER dapat berupa satu layar atau keseluruhan cerita pengguna aplikasi Anda — bayangkan autentikasi, yang dapat berupa satu layar atau beberapa layar terkait. Seberapa kecilkah balok “LEGO” Anda? – Terserah kamu. Pada dasarnya, modul VIPER dapat berupa satu layar atau keseluruhan cerita pengguna aplikasi - pikirkan tentang autentikasi, dapat berupa satu layar atau beberapa layar terkait. Seberapa kecil seharusnya batu bata “LEGO” Anda? - Terserah kamu.

Jika kita bandingkan dengan jenis MV(X), kita akan melihat beberapa perbedaan dalam pembagian tanggung jawabnya: Jika kita membandingkannya dengan tipe MV(X) kita akan melihat beberapa perbedaan dalam pembagian tanggung jawab:

  • Logika Model (interaksi data) bergeser ke Interactor dengan Entitas sebagai struktur data bodoh. Logika model (interaksi data) diubah menjadi struktur data bodoh yang berinteraksi dengan entitas.

  • Hanya tugas representasi UI dari Controller/Presenter/ViewModel yang dipindahkan ke Presenter, namun tidak kemampuan mengubah data. Hanya fungsi presentasi UI dari pengontrol/presenter/viewmodel yang ditransfer ke presentasi, bukan fungsi modifikasi data.

  • VIPER adalah pola pertama yang secara eksplisit membahas tanggung jawab navigasi, yang seharusnya diselesaikan oleh Router. VIPER adalah pola pertama yang secara eksplisit menangani tanggung jawab navigasi, yang harus ditangani oleh router.

Cara yang tepat dalam melakukan perutean merupakan tantangan bagi aplikasi iOS, pola MV(X) tidak mengatasi masalah ini. Perutean yang benar merupakan tantangan bagi aplikasi iOS, dan pola MV(X) tidak dapat menyelesaikan masalah ini.

Contoh ini tidak mencakup perutean atau interaksi antar modul, karena topik tersebut tidak tercakup dalam pola MV(X) sama sekali. Contoh ini tidak melibatkan perutean atau interaksi antar modul, karena pola MV(X) tidak mencakup topik ini sama sekali.


import UIKit

struct Person { // Entity (usually more complex e.g. NSManagedObject)
    let firstName: String
    let lastName: String
}

struct GreetingData { // Transport data structure (not Entity)
    let greeting: String
    let subject: String
}

protocol GreetingProvider {
    func provideGreetingData()
}

protocol GreetingOutput: class {
    func receiveGreetingData(greetingData: GreetingData)
}

class GreetingInteractor : GreetingProvider {
    weak var output: GreetingOutput!
    
    func provideGreetingData() {
        let person = Person(firstName: "David", lastName: "Blaine") // usually comes from data access layer
        let subject = person.firstName + " " + person.lastName
        let greeting = GreetingData(greeting: "Hello", subject: subject)
        self.output.receiveGreetingData(greeting)
    }
}

protocol GreetingViewEventHandler {
    func didTapShowGreetingButton()
}

protocol GreetingView: class {
    func setGreeting(greeting: String)
}

class GreetingPresenter : GreetingOutput, GreetingViewEventHandler {
    weak var view: GreetingView!
    var greetingProvider: GreetingProvider!
    
    func didTapShowGreetingButton() {
        self.greetingProvider.provideGreetingData()
    }
    
    func receiveGreetingData(greetingData: GreetingData) {
        let greeting = greetingData.greeting + " " + greetingData.subject
        self.view.setGreeting(greeting)
    }
}

class GreetingViewController : UIViewController, GreetingView {
    var eventHandler: GreetingViewEventHandler!
    let showGreetingButton = UIButton()
    let greetingLabel = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.showGreetingButton.addTarget(self, action: "didTapButton:", forControlEvents: .TouchUpInside)
    }
    
    func didTapButton(button: UIButton) {
        self.eventHandler.didTapShowGreetingButton()
    }
    
    func setGreeting(greeting: String) {
        self.greetingLabel.text = greeting
    }
    
    // layout code goes here
}
// Assembling of VIPER module, without Router
let view = GreetingViewController()
let presenter = GreetingPresenter()
let interactor = GreetingInteractor()
view.eventHandler = presenter
presenter.view = view
presenter.greetingProvider = interactor
interactor.output = presenter

Sekali lagi, kembali ke fitur: Kembali ke fitur lagi:

  • Distribusi — Tidak diragukan lagi, VIPER adalah pemimpin dalam pembagian tanggung jawab. Distribusi - Tidak diragukan lagi, Viper adalah jagoan dalam mendistribusikan tanggung jawab.

  • Kemampuan pengujian —tidak ada kejutan di sini, distribusi yang lebih baik—kemampuan pengujian yang lebih baik. Testabilitas - tidak ada kejutan di sini, distribusi yang lebih baik - testabilitas yang lebih baik.

  • Mudah digunakan — Terakhir, dua hal di atas memerlukan biaya perawatan seperti yang sudah Anda duga. Anda harus menulis antarmuka dalam jumlah besar untuk kelas dengan tanggung jawab yang sangat kecil. Kemudahan penggunaan – Terakhir, seperti yang sudah Anda duga, kedua item yang disebutkan di atas adalah biaya pemeliharaan. Anda harus menulis banyak antarmuka untuk kelas dengan tanggung jawab yang sangat kecil.

Jadi bagaimana dengan LEGO?

Bagaimana dengan Legonya?Saat menggunakan VIPER, Anda mungkin merasa ingin membangun The Empire State Building dari balok LEGO, dan itu pertanda bahwa Anda mempunyai masalah. Mungkin masih terlalu dini untuk mengadopsi VIPER untuk aplikasi Anda dan Anda harus mempertimbangkan sesuatu yang lebih sederhana. Beberapa orang mengabaikan hal ini dan terus menembakkan meriam ke burung pipit. Saya berasumsi mereka yakin bahwa aplikasi mereka akan mendapat manfaat dari VIPER setidaknya di masa depan, meskipun saat ini biaya pemeliharaannya terlalu tinggi. Jika Anda meyakini hal yang sama, saya sarankan Anda mencoba Generamba — alat untuk menghasilkan kerangka VIPER. Meskipun bagi saya pribadi rasanya seperti menggunakan sistem penargetan otomatis untuk meriam daripada sekadar menembakkan ketapel. Saat menggunakan VIPER, Anda mungkin merasa seperti sedang membangun Empire State Building dari Lego, yang merupakan tanda bahwa Anda memiliki masalah. Mungkin masih terlalu dini untuk mengadopsi VIPER untuk aplikasi Anda dan Anda harus mempertimbangkan beberapa metode yang lebih sederhana. Beberapa orang mengabaikan hal ini dan terus menembaki burung pipit dengan meriamnya. Saya berasumsi mereka yakin aplikasi mereka akan mendapat manfaat dari VIPER setidaknya di masa depan, meskipun biaya pemeliharaan saat ini terlalu tinggi. Jika Anda berpikir demikian, saya sarankan Anda mencoba Generamba - alat untuk menghasilkan kerangka ular berbisa. Meskipun bagi saya pribadi rasanya seperti memotret dengan sistem auto-aim dibandingkan dengan ketapel sederhana.

###Kesimpulan Kesimpulan

Kita telah mempelajari beberapa pola arsitektur, dan saya harap Anda telah menemukan beberapa jawaban atas apa yang mengganggu Anda, namun saya yakin Anda menyadari bahwa tidak ada solusi terbaik jadi memilih pola arsitektur adalah masalah mempertimbangkan pengorbanan dalam situasi khusus Anda. Kita telah membahas beberapa pola arsitektur dan saya harap Anda telah menemukan beberapa jawaban atas pertanyaan-pertanyaan yang selama ini mengganggu Anda, namun saya yakin Anda telah menyadari bahwa tidak ada obat ajaib, jadi memilih pola arsitektur adalah masalah menimbang pro dan kontra dalam situasi spesifik Anda.

Oleh karena itu, wajar jika memiliki perpaduan arsitektur dalam aplikasi yang sama. Misalnya: Anda memulai dengan MVC, lalu Anda menyadari bahwa satu layar tertentu menjadi terlalu sulit untuk dikelola secara efisien dengan MVC dan beralih ke MVVM, namun hanya untuk layar tertentu. Tidak perlu memfaktorkan ulang layar lain yang mana MVC benar-benar berfungsi dengan baik, karena kedua arsitektur tersebut mudah kompatibel. Oleh karena itu, wajar jika menggabungkan arsitektur dalam aplikasi yang sama. Misalnya: Anda memulai dengan MVC, lalu Anda menyadari bahwa sulit mempertahankan layar tertentu secara efisien menggunakan MVC, jadi beralihlah ke MVVM, tetapi hanya untuk layar spesifik ini. Tidak perlu memfaktorkan ulang layar lain di mana MVC benar-benar berfungsi dengan baik, karena kedua arsitektur tersebut mudah kompatibel.

Buatlah segala sesuatunya sesederhana mungkin, namun tidak sesederhana itu—Albert Einstein Buatlah segala sesuatunya sesederhana mungkin, namun jangan sesederhana mungkin - Albert Einstein

Terima kasih telah membaca! Jika Anda menyukai artikel ini, silakan bertepuk tangan agar orang lain juga dapat membacanya :) Terima kasih telah membaca! Jika Anda menyukai postingan ini, silakan bertepuk tangan agar orang lain juga dapat membacanya.

Ikuti saya di Twitter untuk mengetahui lebih banyak desain dan pola iOS. Ikuti saya di Twitter untuk mengetahui lebih banyak desain dan pola iOS.

Teks asli