MVC (Model-View-Controller) — pola arsitektur yang membagi aplikasi menjadi tiga komponen: Model bertanggung jawab atas data dan logika bisnis, View — atas antarmuka pengguna, Controller — atas pemrosesan masukan dan koordinasi Model dan View. Di iOS, MVC diimplementasikan melalui UIViewController, di Android — melalui Activity dan Fragment. MVC tetap menjadi pola dasar yang menjadi fondasi MVVM, MVP, dan Clean Architecture. Selengkapnya — di MVC in Cocoa Core.
Poin Utama
MVC (Model-View-Controller) — pola arsitektur yang diusulkan oleh Trygve Reenskaug pada tahun 1979 untuk bahasa Smalltalk-80. Pola ini membagi aplikasi menjadi tiga lapisan: Model berisi data dan logika bisnis, View bertanggung jawab atas tampilan, Controller memproses masukan pengguna dan memperbarui Model dan View. Pemisahan tanggung jawab memungkinkan perubahan setiap lapisan secara independen — misalnya, mengganti View dari UIKit ke SwiftUI tanpa mengubah logika bisnis di Model.
Interaksi komponen dalam MVC mengikuti siklus: pengguna berinteraksi dengan View → Controller menerima peristiwa → Controller memperbarui Model → Model memberi tahu Controller tentang perubahan → Controller memperbarui View. Dalam implementasi klasik, Model menggunakan pola Observer: saat data berubah, Model mengirimkan pemberitahuan, Controller berlangganan dan memperbarui View. Dalam implementasi Apple, Key-Value Observing (KVO) atau NotificationCenter menjalankan peran ini.
| Komponen | Tanggung Jawab | Contoh di iOS | Contoh di Android |
|---|---|---|---|
| Model | Data, logika bisnis, jaringan | Struct User, CoreData | Data class, Repository |
| View | Tampilan UI | Storyboard, XIB, UIView | Tata letak XML, Jetpack Compose |
| Controller | Pemrosesan masukan, koordinasi | UIViewController | Activity, Fragment |
MVC dalam pengembangan mobile modern lebih jarang digunakan dibandingkan 10 tahun lalu, tetapi tetap wajib dipahami. Apple merekomendasikan MVC untuk layar sederhana di aplikasi UIKit. Google tidak merekomendasikan MVC murni untuk Android — dokumentasi resmi menyarankan MVVM dengan Jetpack. Namun, pengetahuan MVC diperlukan untuk bekerja dengan proyek warisan dan untuk memahami evolusi pola arsitektur.
Apple MVC — implementasi khusus pola yang tertanam di UIKit. UIViewController berperan sebagai Controller: mengelola siklus hidup layar (viewDidLoad, viewWillAppear, viewDidDisappear), memproses sentuhan dan tindakan pengguna, memperbarui View melalui IBOutlets. View dibuat di Interface Builder (storyboard atau XIB) atau secara terprogram. Model — objek data apa pun: layanan jaringan, tumpukan CoreData, struktur Swift.
final class UserViewController: UIViewController {
// View (melalui outlet storyboard)
@IBOutlet private var nameLabel: UILabel!
@IBOutlet private var emailLabel: UILabel!
// Model
private let userService = UserService()
override func viewDidLoad() {
super.viewDidLoad()
loadUser()
}
private func loadUser() {
userService.fetchUser { [weak self] user in
// Controller memperbarui View
self?.nameLabel.text = user.name
self?.emailLabel.text = user.email
}
}
}
Masalah Apple MVC — View dan Controller terikat erat. UIViewController secara bersamaan mengelola View dan logika. Storyboard menyimpan View dalam XML, tetapi kontroler memiliki referensi langsung ke elemen UI melalui IBOutlets. Ini melanggar prinsip tanggung jawab tunggal: kontroler bertanggung jawab atas siklus hidup, delegasi, datasource, target-action, dan animasi. Akibatnya, layar standar aplikasi iOS berisi 200–500 baris di kontroler.
Siklus hidup ViewController — Apple menyediakan 6 metode siklus hidup: loadView (pembuatan View secara manual), viewDidLoad (setelah View dimuat ke memori), viewWillAppear (sebelum muncul di layar), viewDidAppear (setelah animasi), viewWillDisappear (sebelum meninggalkan layar), viewDidDisappear (setelah meninggalkan). Setiap metode — tempat untuk menempatkan logika dalam MVC. Menggunakan metode ini untuk logika bisnis mempercepat pertumbuhan kontroler.
Android MVC — Activity dan Fragment berperan sebagai Controller, file tata letak XML — View, kelas POJO apa pun dengan data — Model. Activity mengelola siklus hidup layar: onCreate, onStart, onResume, onPause, onStop, onDestroy. Fragment — sub-layar di dalam Activity dengan siklus hidup sendiri. View (XML) terpisah dari Controller dan dimuat melalui setContentView atau LayoutInflater. Model — repositori, basis data, panggilan jaringan.
class UserActivity : AppCompatActivity() {
// View melalui tata letak XML
private lateinit var binding: ActivityUserBinding
// Model
private val userRepository = UserRepository()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityUserBinding.inflate(layoutInflater)
setContentView(binding.root)
loadUser()
}
private fun loadUser() {
userRepository.getUser { user ->
runOnUiThread {
binding.nameText.text = user.name
binding.emailText.text = user.email
}
}
}
}
Android ViewBinding dan DataBinding — alat modern yang mengurangi keterikatan Controller dan View. ViewBinding menghasilkan kelas dengan referensi langsung ke View dari XML, menghilangkan findViewById. DataBinding menambahkan kemampuan untuk mengikat data dengan UI dalam markup XML melalui @{user.name}. DataBinding — langkah menuju MVVM, karena memungkinkan mentransfer data dari Model ke View tanpa kode di Activity. Google merekomendasikan DataBinding untuk semua proyek baru.
Siklus hidup Android lebih kompleks daripada iOS: Activity dapat dihancurkan dan dibuat ulang saat rotasi layar, kekurangan memori, atau perubahan konfigurasi. Dalam MVC murni, kontroler (Activity) berisi logika yang hilang saat dihancurkan. Ini memerlukan penyimpanan status melalui onSaveInstanceState atau ViewModel dari Jetpack, yang melampaui kerangka MVC murni dan mendekatkan arsitektur ke MVVM.
Massive View Controller — istilah yang menggambarkan masalah utama MVC dalam pengembangan mobile. Kontroler di iOS dan Android mengambil terlalu banyak tanggung jawab: pemrosesan masukan, validasi data, interaksi jaringan, navigasi, caching, animasi, manajemen siklus hidup. Akibatnya, kontroler membengkak hingga 500–2000 baris kode, menjadi sulit dibaca, diuji, dan dipelihara.
Penyebab Massive View Controller — arsitektur UIKit dan Android Framework mendorong penempatan logika di kontroler. Panggilan jaringan, pemrosesan JSON, navigasi — semua ini secara alami ditulis di Activity atau UIViewController, karena mereka memiliki akses ke siklus hidup dan UI. Pengembang harus secara sadar memindahkan logika ke kelas terpisah (Service, Manager, Interactor), yang memerlukan disiplin dan pemahaman prinsip arsitektur.
| Masalah MVC | Deskripsi | Solusi |
|---|---|---|
| Keterikatan kuat | Controller mengetahui View dan Model | MVVM — ViewModel tidak mengetahui View |
| Sulit diuji | Controller bergantung pada UIKit/Android | Memindahkan logika ke layanan |
| Siklus hidup | Status hilang saat rotasi | ViewModel dari Jetpack/SwiftUI |
| Tidak ada navigasi | Controller mengelola transisi | Pola Coordinator, Router |
Pengujian MVC — Model diuji secara terisolasi dengan pengujian unit. Controller sulit diuji karena ketergantungan pada UIKit/UIFoundation. XCTest tidak memungkinkan pembuatan UIViewController tanpa jendela tampilan. Untuk Android, ActivityTestRule dan Robolectric sebagian memecahkan masalah, tetapi pengujian lambat. View biasanya tidak diuji dengan pengujian unit — untuk UI digunakan pengujian tangkapan layar dan UI (XCUITest, Espresso).
Kapan MVC dibenarkan — layar sederhana dengan satu-dua elemen (layar masuk, profil, pengaturan). Prototipe dan MVP untuk menguji hipotesis — MVC lebih cepat ditulis tanpa lapisan tambahan. Proyek dengan basis kode kecil hingga 10–15 layar. Dalam proyek kompleks, MVC menyebabkan akumulasi utang teknis dan memerlukan refactoring setiap 6–12 bulan.
MVC vs MVVM — perbedaan utama: dalam MVVM, kontroler digantikan oleh ViewModel yang tidak memiliki referensi ke View. Data ditransfer melalui Observable (SwiftUI), LiveData/StateFlow (Android) atau Combine/RxSwift. ViewModel diuji dengan pengujian unit tanpa ketergantungan UI. Apple merekomendasikan MVVM dengan SwiftUI sejak 2019, Google — MVVM dengan LiveData/Flow sebagai arsitektur resmi Android. MVVM memerlukan lebih banyak kode untuk pengikatan, tetapi secara signifikan meningkatkan kemampuan pengujian.
MVC vs MVP — dalam MVP (Model-View-Presenter) Presenter adalah lapisan yang dapat diuji yang menerima View melalui antarmuka. Tidak seperti MVC, di mana Controller langsung mengelola View melalui UIKit, Presenter tidak bergantung pada kerangka kerja — bekerja melalui abstraksi ViewInterface. MVP populer dalam pengembangan Android sebelum munculnya Jetpack dan digunakan dalam proyek lama. Presenter hidup lebih lama dari Activity dan mempertahankan status saat rotasi layar.
MVC vs Clean Architecture — Clean Architecture menambahkan lapisan Use Cases (Interactors), Entities, Gateways, dan Repository. MVC tetap di lapisan Presentation, tetapi logika bisnis dipindahkan ke lapisan Domain dengan Use Cases. Clean Architecture memecahkan masalah Massive View Controller secara radikal — Controller hanya berisi panggilan Use Cases dan pembaruan View. Kelemahannya adalah peningkatan signifikan jumlah kelas dan file, yang dibenarkan untuk proyek dengan 50+ layar.
// MVC di iOS: Controller berisi segalanya
class OrderViewController: UIViewController {
func placeOrder() {
// Validasi + jaringan + pembaruan UI
guard Validation.isValid(total) else { return }
NetworkService.shared.submit(order) { [weak self] result in
self?.handleResult(result)
}
}
}
// MVVM: logika di ViewModel
class OrderViewModel: ObservableObject {
@Published var state: OrderState = .idle
func placeOrder() { /* logika bisnis */ }
}
Pemilihan arsitektur tergantung pada ukuran tim, proyek, dan kemampuan pengujian yang diperlukan. Untuk tim 1–2 pengembang dan proyek hingga 20 layar, MVVM cocok. Untuk tim besar dari 5 pengembang dan proyek dari 50 layar — Clean Architecture dengan struktur modular. MVC tetap relevan untuk memahami evolusi arsitektur, untuk mendukung proyek warisan dan untuk layar sederhana di UIKit tanpa logika bisnis yang kompleks.
Pertanyaan yang Sering Diajukan
Masalah utamanya adalah Massive View Controller. Di iOS, kontroler UIViewController bertanggung jawab atas segalanya: pemrosesan masukan, pembaruan View, bekerja dengan jaringan, navigasi, dan siklus hidup. Di Android, Activity/Fragment menjalankan fungsi serupa. Akibatnya, kontroler membengkak hingga ribuan baris kode, menjadi sulit diuji dan dipelihara, melanggar prinsip tanggung jawab tunggal.
Dalam MVC, kontroler langsung memperbarui View dan memproses masukan pengguna. Dalam MVVM, peran kontroler dijalankan oleh ViewModel yang tidak memiliki referensi ke View — data ditransfer melalui mekanisme pengikatan. MVVM lebih baik diuji karena ViewModel tidak bergantung pada UIKit atau Android Framework. Apple merekomendasikan MVVM dengan SwiftUI, Google — MVVM dengan Jetpack Compose.
Ya, MVC tetap menjadi pola yang berfungsi untuk layar sederhana dan prototipe. Apple merekomendasikan MVC untuk aplikasi UIKit dengan layar sederhana. Untuk proyek kompleks dengan banyak layar, permintaan jaringan, dan caching, lebih baik memilih MVVM, VIPER, atau Clean Architecture. Pengembang pemula disarankan menguasai MVC sebelum mempelajari pola yang lebih kompleks.
Model diuji secara terisolasi — ini adalah objek data biasa dan logika bisnis. Controller sulit diuji karena ketergantungan pada UIKit atau Android Framework. Disarankan untuk memindahkan logika bisnis dari kontroler ke layanan atau interaktor terpisah, yang diuji dengan pengujian unit. View biasanya tidak diuji dengan pengujian unit — untuk itu digunakan pengujian UI dan pengujian tangkapan layar.
Di iOS — MVVM dengan SwiftUI dan Combine, standar Apple sejak 2019. Di Android — MVVM dengan LiveData atau StateFlow, secara resmi direkomendasikan oleh Google. Untuk proyek besar dengan tim dari 5 pengembang — Clean Architecture dengan VIPER di iOS atau Clean Architecture di Android dengan pembagian modul berdasarkan fitur. Untuk proyek warisan dengan MVC — refactoring bertahap dengan memindahkan logika ke layanan terpisah.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga