MVVM Neden Android'de Patladı?
Google'ın Önerdiği Mimari
Bir mimarinin gerçekten yaygınlaşması için genellikle iki şeyin bir araya gelmesi gerekir: çözdüğü sorunun gerçek ve acı verici olması, ve arkasında onu destekleyen güçlü bir otoritenin bulunması.
MVVM için bu iki koşul mükemmel biçimde bir araya geldi.
MVVM Nedir?
MVVM, Model - View - ViewModel üçlüsünden oluşur. Microsoft tarafından WPF ve Silverlight platformları için tasarlandı. Ama Android'de Google'ın 2017'de tanıttığı Jetpack bileşenleriyle birlikte yeni bir anlam kazandı.
Model önceki mimarilerle aynı roldedir. Veri kaynakları, repository'ler, iş mantığı burada yaşar.
View kullanıcı arayüzünü oluşturur. Activity, Fragment ve Composable'lar bu role girer. View, ViewModel'i gözlemler ve gelen veriyi gösterir.
ViewModel ise MVP'deki Presenter'a benzer ama kritik bir farkla: ViewModel, View'dan tamamen habersizdir. Presenter View arayüzünü tutarken, ViewModel hiçbir View referansı taşımaz. Bunun yerine gözlemlenebilir veri akışları yayınlar.
Gözlemlenebilirlik: Oyunun Kurallarını Değiştiren Fikir
MVP'de Presenter, View'a aktif olarak talimat verir. "Şu metni göster, şu butonu devre dışı bırak" der. Bu ilişki Presenter'ı View'a bağlar.
MVVM'de ilişki tersine döner. ViewModel veriyi bir akışa koyar ve oradan ayrılır. View bu akışı dinler ve veri değiştikçe kendini günceller.
Bu yaklaşıma reaktif programlama denir ve beraberinde derin bir zihniyet değişikliği getirir. "Ne gösterilsin?" sorusunun cevabı artık Presenter'ın kafasında değil, verinin kendisindedir. Veri ne durumdaysa UI o durumu yansıtır.
LiveData ve StateFlow bu akışların Android'deki somut araçlarıdır.
Google'ın Jetpack Atılımı: 2017 Dönüm Noktası
MVVM Android'de bu kadar hızlı yaygınlaştıysa bunda Google'ın 2017 I/O konferansında tanıttığı Architecture Components paketinin payı büyüktür.
Bu paketle birlikte üç kritik bileşen sahneye çıktı.
ViewModel, configuration change boyunca yaşayan ve View referansı taşımayan bir sınıftır. Ekran döndürüldüğünde Activity yeniden oluşturulur ama ViewModel ayakta kalır. Yeni Activity aynı ViewModel'e bağlanır ve veri kaybolmaz. Bu tek özellik, MVP'nin çözemediği configuration change sorununu kökten çözdü.
LiveData, lifecycle'a duyarlı gözlemlenebilir bir veri tutucusudur. Activity durduğunda observer'lar otomatik olarak devre dışı kalır, Activity yeniden başladığında tekrar aktifleşir. Arka plandan UI güncellemesi yapma tehlikesi ortadan kalkar. Bellek sızıntısı riski minimuma iner.
Room, SQLite üzerine inşa edilmiş ve LiveData ile doğrudan entegre çalışan bir veritabanı kütüphanesidir. Veritabanı değiştiğinde UI otomatik olarak güncellenir — tek satır ekstra kod yazmadan.
Boilerplate'in Azalması
MVP'nin en çok şikâyet edilen özelliği boilerplate koddu. Her View için bir arayüz, her metot için bir implementasyon, her değişiklik için üç ayrı dosyada güncelleme.
MVVM bu yükü önemli ölçüde azalttı. View arayüzü yazmak gerekmez. Presenter'dan View'a her talimat için ayrı bir metot tanımlamak gerekmez. ViewModel bir LiveData ya da StateFlow yayınlar, View bunu gözlemler — hepsi bu.
Daha az kod, daha az hata, daha kolay bakım.
Kotlin ve Coroutines ile Mükemmel Uyum
MVVM'in Android'deki yayılmasını hızlandıran bir diğer etken, Kotlin ve Coroutines ile olan doğal uyumudur.
Kotlin'in flow ve StateFlow yapıları, reaktif veri akışlarını yazmayı son derece doğal hale getirdi. ViewModel içinde bir Coroutine başlatmak, ağdan veri çekmek ve sonucu bir StateFlow'a yazmak birkaç satırlık temiz kodla yapılabiliyor. View tarafında bu flow'u toplamak da aynı derecede basit.
Bu kombinasyon MVVM'i yalnızca teorik olarak değil, pratik olarak da cazip hale getirdi.
Compose: MVVM'i Daha Da Güçlendiren Adım
Jetpack Compose ile birlikte MVVM-Compose ikilisi Android geliştirmenin yeni standardına dönüştü.
Compose'un reaktif ve state-driven yapısı MVVM ile doğal bir uyum içindedir. ViewModel'den gelen state Composable'lara akar, Composable'lar bu state değiştikçe otomatik olarak yeniden çizilir. Lifecycle yönetimi çerçeve tarafından üstlenilir, geliştirici iş mantığına ve UI'a odaklanır.
MVVM'in Sınırları
MVVM her derde deva değildir. Karmaşık uygulamalarda ViewModel'ler şişmeye başlayabilir. İş mantığı, ViewModel içine sıkışabilir. Farklı katmanlar arasındaki sınırlar zamanla bulanıklaşabilir.
Bu sorunlar MVVM'i terk etmenin değil, üzerine daha güçlü bir yapı inşa etmenin gerekçesi oldu. Clean Architecture tam da bu noktada devreye girdi.