MVP Neden Çıktı?
MVC'nin Bıraktığı Boşluğu Doldurmak
MVC'nin Android'deki en büyük sorunu netti: Activity hem çok fazla iş yapıyor hem de test edilmesi son derece zordu. Çözüm için gereken şey, iş mantığını Android framework'ünden ayıracak bir katmandı.
Bu ihtiyaç MVP'yi doğurdu.
MVP Nedir?
MVP, Model - View - Presenter üçlüsünden oluşur. MVC'den ilham alır ama Controller'ın yerini Presenter alır ve bu değişiklik görünenden çok daha derin sonuçlar doğurur.
Model MVC ile aynıdır. Veri, iş mantığı ve dış dünyayla iletişim burada yaşar. Veritabanı, ağ, önbellek — bunların tamamı Model'in sorumluluğundadır.
View kullanıcı arayüzünü temsil eder. Ama MVP'de View, MVC'dekinden çok daha pasif bir role bürünür. View yalnızca Presenter'ın söylediklerini gösterir ve kullanıcı etkileşimlerini Presenter'a bildirir. Hiçbir karar almaz, hiçbir mantık içermez.
Presenter ise gerçek farkın yaşandığı yerdir. Presenter, View ile Model arasındaki köprüdür. Kullanıcı etkileşimlerini alır, Model'e danışır, gelen sonuçla ne yapılacağına karar verir ve View'a talimat verir.
MVC'den MVP'ye: Asıl Fark
MVC'de Controller, View'ı doğrudan manipüle eder. Android bağlamında bu, Activity'nin hem mantık hem de UI yönetimini üstlenmesi demekti.
MVP'de bu ilişki tersine döner. Presenter, View'ı doğrudan tanımaz. View ile Presenter arasında bir arayüz (interface) bulunur. Presenter bu arayüz üzerinden View'a talimat verir — ama View'ın gerçekte ne olduğunu bilmez.
Bu ayrım kâğıt üzerinde ince görünebilir. Ama pratikteki sonucu devrimseldir: Presenter Android framework'ünden bağımsız hale gelir.
Test Edilebilirlik: MVP'nin Asıl Kazanımı
Presenter saf bir Java ya da Kotlin sınıfıdır. Android import'u içermez, Context kullanmaz, Activity'ye bağımlı değildir.
Bu ne anlama gelir? Presenter'ı test etmek için Android ortamına gerek yoktur. View arayüzünü bir mock nesnesiyle taklit edebilirsiniz, Model'i mock'layabilirsiniz ve Presenter'ı saf JVM testleriyle çalıştırabilirsiniz.
Testler saniyelerde çalışır, güvenilirdir ve yazmak kolaydır. "Kullanıcı butona basınca doğru şey oluyor mu?" sorusunu cihaz olmadan, emülatör olmadan, yalnızca kod çalıştırarak yanıtlayabilirsiniz.
Bu, MVC'de neredeyse imkânsız olan bir şeydi.
View Pasifleşir, Sorumluluk Netleşir
MVP'nin bir diğer önemli katkısı sorumluluk sınırlarını netleştirmesidir.
Activity ya da Fragment artık yalnızca View rolünü üstlenir. Layout inflate eder, View'ları günceller, kullanıcı etkileşimlerini Presenter'a iletir. Bunların ötesinde hiçbir karar almaz.
"Kullanıcı giriş yaptıktan sonra hangi ekrana gidilsin?" sorusunun cevabı artık Activity'de değil Presenter'dadır. "Veriler yüklenirken yükleme göstergesi gösterilsin mi?" kararı Activity'nin değil Presenter'ın sorumluluğundadır.
Bu netlik büyük takımların birlikte çalışmasını kolaylaştırdı. View tarafında çalışan geliştirici ile iş mantığını yazan geliştirici birbirinin koduna dokunmadan paralel ilerleyebiliyordu.
MVP'nin Kendi Sorunları
MVP bir adım ileriydi ama mükemmel değildi.
En büyük sorun View - Presenter sözleşmesinin büyümesiydi. Her View için bir arayüz yazılıyordu. Her arayüz büyüdükçe yönetmek zorlaşıyordu. Küçük bir değişiklik arayüzü, View implementasyonunu ve Presenter'ı aynı anda güncellemeyi gerektiriyordu.
Bir diğer sorun Presenter'ın lifecycle'ı yönetmesinin zorluğuydu. Android Activity'nin döngüsü karmaşıktır. Ekran döndürülünce ne olacak? Presenter yeniden mi oluşturulacak? Eski Presenter bellekte kalacak mı? Bu soruların cevapları boilerplate koda dönüşüyordu.
Ve belirli bir noktadan sonra Presenter'lar da şişmeye başladı. Tüm iş mantığını tek bir sınıfa yığmak MVC'den farklı değildi — yalnızca sorun Activity'den Presenter'a taşınmıştı.
Bu sınırlar, MVVM'in sahneye çıkışını hazırladı.
MVP'nin Kalıcı Mirası
MVP Android topluluğunu test edilebilir kod yazmaya alıştırdı. İş mantığının UI'dan ayrılması gerektiği fikrini pratikte kanıtladı.
Bugün MVP'yi aktif olarak benimseyen yeni projeler azalmış olsa da MVP'nin öğrettiği prensipler MVVM ve Clean Architecture'ın içinde yaşamaya devam ediyor.