Android Uygulama Geliştirmede MVC, MVP, MVVM ve MVI Mimarilerinin Kullanımı(Bölüm 1)
Android’de uygulama geliştirme yaparken uygulamamızın sürdürülebilir, kolayca genişletilebilir ve organize edilebilir olmasını amaçlarız. Bu sebeplerden kod parçalarını belirli sorumluluklar dahilinde farklı bölümlere ayırma ihtiyacı duyarız. Android dünyasında yaygın olarak kullanılmış ve kullanılmaya devam eden bazı mimarileri inceleyeceğiz.
Tüm mimarilerin anlatımını basit bir Counter uygulaması üzerinden gerçekleştireceğiz ve 2 bölümden oluşacaktır. MVC, MVP ve MVVM için UML (Unified Modeling Language) diyagramları oluşturacak, MVI için ise doğrudan Orbit kütüphanesinin basitleştirilmiş bir versiyonunu kodlar üzerinden anlatmaya çalışacağım.
Birinci bölümde, aşağıdaki başlıklara değineceğiz:
- MVC
- MVP
- MVVM
İkinci bölümde ise MVI mimarisini anlatmaya çalışacağım.
MVC Mimarisi
MVC mimarisi Model, View, Controller’dan oluşan bir mimaridir.
View, ekranda görünecek nesnelerin çizildiği ve kullanıcının etkileşime geçtiği yerdir.
Controller, View kısmındaki etkileşimin yönlendirildiği yerdir. Örneğin bir butona basıldıktan sonra ne olacağına controller kısmında yer verilir.
Model: Controller’ın ve View’in etkileşime geçtiği ve verinin tutulduğu yerdir. Örneğin Repository katmanı veya Shared Preferences olabilir.
MVC mimarisinin basit bir counter uygulaması için UML tasarımı şu şekilde olabilir:
- CounterModel, verinin alındığı ve güncellendiği yerdir. Veriyi güncellemek için ‘increment’ ve ‘decrement’ metodları bulunmaktadır.
- CounterView, Model güncellendiğinde CounterView interface’i içerisindeki onCounterValueChange() metodu Activity tarafından çağrılır ve View güncellenir.
- CounterViewImpl, sınıfı ise kullanıcının gördüğü her şeyi ekrana çizdirir ve event’leri CounterViewActions interface’i aracılığıyla controller’a aktarır.
- CounterActivty, CounterViewActions’ı implemente ederek View tarafından ‘increment’ veya ‘decrement’ butonlarına basıldığında event’leri yakalar. Ardından Model’i günceller ve sonrasında onCounterValueChanged ile View’i günceller.
Artılar
- Model View ve Controller için SRP uygulanabiliyor.
- Android component’lerini implement etmeyen sınıflar için test edilebilirlik kolay.
Eksiler
- Sınıflar birbirleriyle interface’ler vasıtasıyla bile olsa birbirlerine oldukça bağlı. (Tightly Coupled)
MVP Mimarisi
MVP mimarisi, Model-View-Presenter yapısından oluşur ve MVC mimarisine oldukça benzer. MVC’de Model verisi değiştiğinde, Controller View’e Modelin güncellendiği bilgisini iletir ve ardından View Model’den son veriyi çekerdi. Ancak MVP’de View, doğrudan Model ile iletişim kurmaz; bunun yerine Presenter aracılığıyla güncel veriyi alır ve View güncellenir. MVP’de View, sadece datayı render etmekten sorumludur ve View ile Model arasında doğrudan bir ilişki bulunmaz.
View, ekranda görünecek nesnelerin çizildiği ve kullanıcının etkileşime geçtiği yerdir.
Presenter, View kısmından gelen event’lerin yönlendirildiği yerdir. Modeldeki veriyi manipüle eder ve View’ı günceller.
Model, ise verilerin geldiği yerdir. Presenter tarafından güncellenir.
UML tasarımı:
CounterModel verinin geldiği yer.
CounterActivty, MVP’de View görevi görür ve kullanıcı arttırma veya azaltma gibi butonlara bastığında Activty tarafında yakalanır; ve CounterPresenter interface’i aracılığıyla CounterPresenterImpl sınıfına delege edilir.
Counter PresenterImpl, View tarafından gelen çağrılara göre Model tarafına ulaşarak veriyi günceller CounterView interface’i aracılığıyla View’i günceller.
Artılar
- MVC’den farklı olarak, MVP’de View ve Model arasında doğrudan ilişki bulunmaz, bu da daha esnek bir yapı sağlar.
Eksiler
- MVC de olduğu gibi çok fazla interface yazmak gerekebilir bu da kompleksliği arttırır.
MVVM Mimarisi
MVVM Model, View ve ViewModel katmanlarından oluşur. Bu mimari, MVP ve MVC’deki gibi katmanlar arası iletişim için interface gerekliliğini ortadan kaldırmıştır. View, ViewModel içerisindeki observable yapılar sayesinde, herhangi bir interface çağrımına gerek duymadan, kendini tekrardan render edebilir.
View, ekranda görünecek nesnelerin çizildiği ve kullanıcının etkileşime geçtiği yerdir. ViewModel içerisindeki bir veya birden fazla observable alanı observe edebilir.
ViewModel: View tarafından observe edilebilir alanları barındırır. Model katmanı ve View arasında ara bir katman görevi görür.
Model: MVP ve MVC deki gibidir Repository, API katmanı gibi şeyler olabilir.
Counter uygulaması UML tasarımı:
CounterModel, verinin geldiği yer.
CounterActivity, View görevi görür ve kullanıcı arttırma veya azaltma gibi butonlara bastığında Activity tarafında yakalanır ve CounterViewModel’e delege edilir.
CounterViewModel, View tarafından gelen çağrılara göre Model tarafına ulaşarak veriyi günceller ardından LiveData tipinde olan count alanını günceller. count alanı güncellendiğinde onu observe eden CounterActivty güncel değeri alır ve View’ı günceller.
Artılar
- MVP ve MVC’ye göre daha esnektir. (Loosely Coupled)
- View, datayı manuel olarak çekmeye veya interface kullanarak güncellenilmesine ihtiyaç duymaz; değişiklikleri anında uygular.
- ViewModel, View ile iletişim için interface’e ihtiyaç duymaz ve ViewModel’ı test etmek daha kolaydır, çünkü View’ı mock’lamaya gerek yoktur.
- Databinding sayesinde Activity ve Fragment sınıfları daha az kod içerir.
Eksiler
- Observe edilen property sayısı arttığında UI tarafı karmaşıklaşabiliyor.
- Databinding kullanıldığında, debug süreci karmaşık hale gelebilir ve build süresi artabilir.
Yazının devamı ikinci bölümde.