MVVM ve Clean Architecture Mobil Uygulamalarda Nasıl Kullanılır?

Yazar: Fatih ŞahinYayın: 27 Ağu 2026Güncelleme: 11 Eyl 202610 dk Okuma

Mobil uygulamalarda MVVM ve Clean Architecture kullanımı, iş mantığı ile kullanıcı arayüzünü ayırarak kod test edilebilirliğini ve sürdürülebilirliğini ölçeklendirir.

MVVM ve Clean Architecture Mobil Uygulamalarda Nasıl Kullanılır? için öne çıkan görsel
MVVM ve Clean Architecture Mobil Uygulamalarda Nasıl Kullanılır? için öne çıkan görsel

Mobil uygulama geliştirmede teknik borcu minimize etmek ve ekipler arası geliştirme hızını korumak için MVVM ve Clean Architecture Mobil Uygulamalarda Nasıl Kullanılır sorusunun yanıtı, mimari katmanların net sınırlarla ayrılmasında yatar. Presentation, Domain ve Data katmanlarını birbirinden bağımsız hale getiren bu yaklaşım; karmaşık iş kurallarını kullanıcı arayüzü ve veri tabanı gibi dış bağımlılıklardan tamamen izole eder. Bu rehber; iOS (Swift/SwiftUI) ve Android (Kotlin/Jetpack Compose) ekosistemlerinde sürdürülebilir, test edilebilir ve kurumsal standartlara uygun bir mimari yapıyı adım adım kurgulamanız için gerekli tüm teknik ve stratejik prensipleri detaylandırmaktadır.

Mobil Projelerde Neden İkili Mimari Yaklaşımına İhtiyaç Duyulur?

Mobil uygulama projeleri büyüdükçe karşılaşılan en temel problem, arayüz (UI) bileşenleri ile iş mantığının (business logic) birbirine sıkı sıkıya bağlanmasıdır. Standart bir Model-View-ViewModel (MVVM) yaklaşımı, Activity, Fragment veya View yapılarındaki karmaşayı azaltmak için ViewModel katmanını devreye sokar. Ancak tek başına MVVM, uygulamanın büyümesiyle birlikte yetersiz kalır. Zamanla ViewModel sınıfları yüzlerce satırlık kod yığınlarına dönüşür; doğrudan API çağrıları, veri tabanı sorguları, veri dönüşümleri ve karmaşık validasyon kuralları ViewModel içine yığılır. Bu durum "Massive ViewModel" problemini doğurur ve kodun bakımını imkansız hale getirir.

Clean Architecture, Robert C. Martin (Uncle Bob) tarafından ortaya konan ve yazılımın merkezine saf iş mantığını yerleştiren bir paradigmadır. Bu mimari, kullanıcı arayüzü kütüphanelerini, veri tabanlarını, ağ istemcilerini veya işletim sistemi servislerini birer "ayrıntı" (detail) olarak konumlandırır. Clean Architecture'ın getirdiği katı katman ayrımı, MVVM'in kullanıcı arayüzü tarafındaki reaktif state yönetimi gücüyle birleştiğinde, her iki dünyanın avantajları tek bir sistemde buluşur. Presentation katmanında MVVM kullanılırken, arka planda uygulamanın tüm kuralları Clean Architecture prensiplerine göre izole edilir.

Bu ikili yaklaşımın tercih edilmesindeki en kritik etken sürdürülebilirlik ve ölçeklenebilirliktir. Büyük ölçekli mobil projelerde ekipler genellikle UI geliştiricileri, core logic mimarları ve backend/data entegrasyon mühendisleri şeklinde özelleşir. Katmanlar doğru soyutlandığında, arayüz tasarımındaki bir değişiklik iş mantığını etkilemezken, API uç noktasındaki bir veri formatı değişimi de kullanıcı arayüzünü doğrudan bozmaz. Kod tabanı modüler hale gelir, birleştirme çakışmaları (merge conflicts) azalır ve yeni özelliklerin sisteme eklenme süresi kısalır.

KARŞILAŞTIRMA TABLOSU

Karşılaştırma Tablosu

Kriter bazında avantajlar ve dezavantajları karşılaştırın.

Kriter
Avantajlar
Dezavantajlar
01 Yalnızca MVVM
UI ve State Yönetimi
Orta (ViewModel mock bağımlılıkları yüksektir)
02 Yalnızca Clean Architecture
İş Mantığı İzolasyonu
Çok Yüksek (Saf veri sınıfları)
03 MVVM + Clean Architecture
Uçtan Uca Ayrım (UI + Logic + Data)
Mükemmel (Her katman izole test edilebilir)
01

Yalnızca MVVM

Avantaj

UI ve State Yönetimi

Dezavantaj

Orta (ViewModel mock bağımlılıkları yüksektir)

02

Yalnızca Clean Architecture

Avantaj

İş Mantığı İzolasyonu

Dezavantaj

Çok Yüksek (Saf veri sınıfları)

03

MVVM + Clean Architecture

Avantaj

Uçtan Uca Ayrım (UI + Logic + Data)

Dezavantaj

Mükemmel (Her katman izole test edilebilir)

Temel Kavramlar: MVVM ve Clean Architecture Kesişimi

MVVM ve Clean Architecture birbirine rakip değil, birbirini tamamlayan iki farklı soyutlama seviyesidir. MVVM bir arayüz tasarım deseni (UI Design Pattern) iken, Clean Architecture bütünsel bir sistem mimarisidir (System Architectural Pattern). Bu iki yapının entegrasyonunda, MVVM tamamen Clean Architecture şemasının en dış halkalarından biri olan Presentation katmanına yerleşir. Geriye kalan Domain ve Data katmanları ise Clean Architecture kurallarına göre şekillendirilir.

Presentation Katmanında MVVM’in Rolü

Presentation katmanının birincil görevi, kullanıcıya veriyi sunmak ve kullanıcıdan gelen etkileşimleri sisteme iletmektir. Bu katmanda yer alan View (SwiftUI View, UIKit UIViewController, Jetpack Compose Composable veya Android Activity/Fragment), sadece görünüm elemanlarının yerleşiminden ve çiziminden sorumludur. View içinde hiçbir iş kuralı, veri tabanı işlemi veya hesaplama mantığı barındırılmaz. View, ViewModel tarafından üretilen UI durumunu (UI State) dinler ve ekrana yansıtır.

ViewModel ise View ile iş mantığı arasındaki köprüdür. UI'ın ihtiyaç duyduğu durumları (Loading, Success, Error vb.) reaktif veri akışları (Kotlin StateFlow/SharedFlow veya Swift Combine/AsyncSequence) ile yayınlar. ViewModel, doğrudan veri tabanına veya ağ istemcisine gitmek yerine, Domain katmanında tanımlanmış Use Case (Interactor) sınıflarını çağırır. Böylece ViewModel, verinin nereden geldiğini bilmeden sadece gelen veriyi UI'ın anlayacağı formatta bir State nesnesine dönüştürür.

Clean Architecture ile İş Mantığının İzolasyonu

Clean Architecture, bir yazılım projesinin en değerli parçası olan iş kurallarını (Business Logic) dış dünyadaki her türlü değişimden koruma prensibine dayanır. Domain katmanı, uygulamanın çekirdeğidir ve tamamen platform bağımsızdır. Android veya iOS SDK'larına, üçüncü parti kütüphanelere ya da framework bileşenlerine bağımlılık içermez. Saf Swift veya saf Kotlin kodlarından oluşur.

İş mantığının izolasyonu sayesinde, uygulamanın kullandığı ağ kütüphanesi (Retrofit'ten Ktor'a veya URLSession'dan Alamofire'a) ya da veri saklama yöntemi (Room'dan Realm'e veya CoreData'dan SwiftData'ya) değiştiğinde, Domain katmanındaki Use Case ve Entity sınıflarına tek bir satır dahi dokunulması gerekmez. Bu izolasyon, SOLID prensiplerinin, özellikle de Tek Sorumluluk Prensibi (Single Responsibility Principle) ve Bağımlılıkların Tersine Çevrilmesi Prensibinin (Dependency Inversion Principle) doğrudan bir sonucudur.

Katmanlı Mimari Tasarımı ve Doğru Entegrasyon Adımları

Mobil projelerde Clean Architecture ile MVVM entegrasyonu üç ana katman üzerinden kurgulanır: Domain, Data ve Presentation. Bu katmanların her biri modüler mimaride ayrı birer bağımsız kütüphane/modül (Gradle module veya Swift Package) olarak da tasarlanabilir. Katmanlar arasındaki sınırların net çizilmesi, projede disiplinli bir kod akışı sağlar.

SÜREÇ ADIMLARI

Clean Architecture Entegrasyon Adımları

Kurumsal mobil uygulamalarda katmanlı mimari kurulumunun teknik işlem sırası.

01

Domain Katmanının Tanımlanması

Entity modelleri, Use Case sınıfları ve Repository arayüzleri platform bağımsız olarak kurgulanır.

02

Data Katmanının İnşa Edilmesi

Repository arayüzleri uygulanır, yerel (Local) ve uzak (Remote) veri kaynakları entegre edilir.

03

Presentation Katmanı ve State Akışının Kurulması

ViewModel içinde Use Case bağımlılıkları enjekte edilir ve View bileşeni reaktif State dinlemeye başlar.

1. Domain Katmanı: Çekirdek Kurallar ve Use Case Yapısı

Domain katmanı, sistemin ne yaptığını tanımlayan iş kurallarını içerir. Bu katmanda üç temel yapı bulunur:

  • Entity: Uygulamanın en saf veri modelleridir. JSON parse etme etiketleri (Codable, SerializedName vb.) veya veri tabanı anotasyonları (Entity, ColumnInfo vb.) içermez. Yalnızca iş mantığının tanıdığı ham veri yapılarıdır.

  • Use Case (Interactor): Tek bir işlevsel görevi yerine getiren sınıflardır. Örneğin LoginUseCase, GetUserUseCase veya GetProductsUseCase. Her Use Case tek bir sorumluluğa sahiptir ve genellikle invoke veya execute fonksiyonu üzerinden çağrılır.

  • Repository Interfaces (Arayüzler): Domain katmanı veriye ihtiyaç duyduğunda bunu Data katmanından doğrudan istemez. Bunun yerine UserRepository gibi soyut bir interface tanımlar. Verinin nasıl getirileceğini bilmez, sadece hangi fonksiyonların var olduğunu belirtir.

2. Data Katmanı: Repository Deseni ve Veri Kaynakları

Data katmanı, Domain katmanının tanımladığı soyut repository arayüzlerinin somut implementasyonlarını barındırır. Bu katmanın amacı, veriyi farklı kaynaklardan (REST API, GraphQL, Local SQLite, DataStore, Keychain) toplamak ve Domain katmanına iletmektir.

  • Data Sources (Veri Kaynakları): İki ana grupta toplanır: RemoteDataSource (Network servisleri, WebSocket) ve LocalDataSource (Room, SwiftData, SharedPreferences, In-Memory Cache).

  • Data Transfer Objects (DTO): Backend API'sinden dönen ham JSON yanıtlarını eşleyen modellerdir. DTO'lar, Domain Entity modellerine dönüştürülmek üzere Mapper fonksiyonları ile eşlenir. Böylece backend'deki bir alan adı değiştiğinde sadece Mapper ve DTO güncellenir; uygulamanın çekirdek iş mantığı etkilenmez.

  • Repository Implementation: Domain arayüzünü uygular. Örneğin UserRepositoryImpl, önce yerel önbelleğe bakar, veri yoksa uzak sunucudan çeker, yerel veri tabanını günceller ve sonucu Domain Entity formatında geriye döner.

3. Presentation Katmanı: ViewModel ve Reaktif State Yönetimi

Presentation katmanı, kullanıcı arayüzünü oluşturan bileşenleri ve bu bileşenlerin durumunu yöneten yapıları barındırır. Modern mobil mimaride (Jetpack Compose ve SwiftUI) Unidirectional Data Flow (UDF - Tek Yönlü Veri Akışı) prensibi esastır.

ViewModel, Domain katmanındaki Use Case'leri çağırarak elde ettiği sonuçları tek bir immutable (değiştirilemez) UI State sınıfında birleştirir. Örneğin:

// Android / Kotlin State Temsili
sealed interface CartUiState {
    object Loading : CartUiState
    data class Success(val cartItems: List<CartItem>, val totalAmount: Double) : CartUiState
    data class Error(val message: String) : CartUiState
}

View, bu State nesnesini gözlemler ve ekrandaki çizimi günceller. Kullanıcı bir butona bastığında (Intent/Event), bu eylem doğrudan ViewModel'e bir fonksiyon çağrısı olarak iletilir. ViewModel ilgili Use Case'i tetikler, veri güncellenir ve yeni State üretilerek View'a aktarılır. Bu döngü sayesinde arayüz ile veri yönetimi arasında tam bir senkronizasyon sağlanır.

Veri Akışı ve Bağımlılık Kuralları (Dependency Rule)

Clean Architecture'ın en kritik kuralı Bağımlılık Kuralı (The Dependency Rule) olarak adlandırılır. Bu kurala göre; kaynak kod bağımlılıkları daima içeriye, yani daha yüksek seviyeli politikalara (Domain katmanına) doğru yönelmelidir. İçteki bir katman, dıştaki hiçbir katman hakkında bilgi sahibi olamaz.

Bu kural şu pratik sonuçları doğurur:

  • Domain Katmanı: Ne Data katmanını ne de Presentation katmanını tanır. İçinde Retrofit veya UIKit gibi ifadeler asla bulunamaz.

  • Data Katmanı: Domain katmanını tanır çünkü onun tanımladığı Repository arayüzlerini implemente eder. Ancak Presentation katmanını tanımaz.

  • Presentation Katmanı: Domain katmanını tanır çünkü Use Case sınıflarını çalıştırır. Ancak Data katmanını (DTO'ları veya somut Repository sınıflarını) doğrudan tanımamalıdır.

[Presentation: View -> ViewModel] ---> (çağırır) ---> [Domain: Use Case]
                                                            ^
                                                            | (uygular)
                                                [Data: RepositoryImpl]

Burada ortaya çıkan paradoks şudur: Kontrol akışı (Flow of Control) Presentation'dan başlayıp Domain üzerinden Data'ya doğru ilerlerken, kaynak kod bağımlılığı ters yönde olmalıdır. Bu problem Bağımlılıkların Tersine Çevrilmesi (Dependency Inversion Principle - DIP) ile çözülür. Domain katmanı sadece bir interface açar; Data katmanı bu interface'i doldurur. Çalışma zamanında (runtime) bu iki parçayı birbirine bağlayan mekanizma ise Bağımlılık Enjeksiyonu (Dependency Injection - DI) araçlarıdır (Android için Hilt/Koin, iOS için Needle/Factory/Swinject).

Dikkat Edilmesi Gerekenler ve Yaygın Mimari Hatalar

MVVM ve Clean Architecture kurgulanırken geliştiricilerin en çok düştüğü hatalar, mimariyi projenin gerçek ihtiyaçlarından koparıp teorik bir kural setine hapsetmekten kaynaklanır. Doğru uygulanmayan bir mimari, fayda sağlamak yerine geliştirme sürecini yavaşlatan bir bürokrasiye dönüşebilir.

Aşırı Mühendislik (Over-Engineering) Riski

En sık yapılan hata, hiçbir iş kuralı içermeyen basit CRUD (Create, Read, Update, Delete) operasyonları için dahi onlarca ara sınıf üretmektir. Bir profil sayfasında sadece kullanıcının adını getiren bir istek için; ViewModel -> UseCase -> Repository -> DataSource -> ApiService zincirinde, UseCase sınıfının tek görevi Repository'deki fonksiyonu doğrudan çağırmaksa (pass-through use case), bu durum gereksiz kod kalabalığı yaratır.

İş mantığı barındırmayan senaryolarda ViewModel'in doğrudan Repository ile konuşmasına izin veren pragmatik yaklaşımlar tercih edilebilir. Ancak finansal hesaplamalar, veri doğrulama, birden fazla kaynaktan veri birleştirme gibi kuralların bulunduğu her durumda Use Case kullanımı zorunlu tutulmalıdır.

Katmanlar Arası Veri Sızıntısı (Data Leakage)

Bir diğer kritik hata, Data katmanına ait modellerin (DTO veya Entity Framework/Room nesneleri) Presentation katmanına kadar sızdırılmasıdır. Örneğin, backend API'sinden gelen UserResponseDTO nesnesinin doğrudan UI ekranında parametre olarak kullanılması, Data katmanı ile Presentation katmanını birbirine bağımlı hale getirir. Backend tarafında bir JSON anahtarı değiştiğinde View bileşeni derleme hatası verir.

Bu hatayı önlemek için her katmanın kendi veri modeline sahip olması ve katman geçişlerinde Mapper sınıfları ile dönüştürme yapılması gerekir:

  1. API'den gelen: UserDTO (Data Katmanı)

  2. İş mantığında işlenen: User (Domain Katmanı)

  3. Ekranda gösterilen: UserUiModel (Presentation Katmanı - Formatlanmış para birimleri, yerelleştirilmiş tarih dizgileri vb.)

Kurumsal Çapta Ölçeklendirme ve Test Edilebilirlik

Kurumsal mobil projelerde Clean Architecture ve MVVM kombinasyonunun en büyük getirisi Test Edilebilirlik (Testability) alanında ortaya çıkar. Mobil platformlarda UI ve cihaz bağımlı testler (Espresso, XCTest UI) yavaş çalışır ve bakımı maliyetlidir. Clean Architecture sayesinde, uygulamanın kritik iş mantığının %80'inden fazlası cihaz emülatörüne ihtiyaç duymadan, saniyeler içinde çalışan saf JVM veya Swift Unit Testleri ile doğrulanabilir.

  • Domain Katmanı Testleri: Use Case sınıfları hiçbir dış framework'e bağlı olmadığı için, Repository arayüzleri kolayca mock'lanabilir (Mockito, MockK, Swift Mocking). İş kuralları tüm uç senaryolar (edge cases) için izole şekilde test edilir.

  • ViewModel Testleri: ViewModel'e mock Use Case'ler verilerek, belirli senaryolar karşısında doğru State nesnelerini üretip üretmediği doğrulanır. Ağ bağlantısı veya veri tabanı olmadan UI akış mantığı garanti altına alınır.

  • Data Katmanı Testleri: Repository implementasyonları test edilirken gerçek API yerine MockWebServer kullanılarak ağ hataları, zaman aşımı (timeout) ve bozuk JSON durumları simüle edilir.

Kurumsal Mobil Projeler İçin Mimari Karar Özeti ve Uygulama Stratejisi

MVVM ve Clean Architecture mimarisini benimsemek, bir mobil projenin başlangıç maliyetini ve geliştirme süresini ilk aşamada yaklaşık %20 ila %30 oranında artırabilir. Katmanların ayrılması, interface'lerin yazılması, DTO-Entity dönüşümlerinin kurgulanması ve Dependency Injection modüllerinin yapılandırılması ek bir efor gerektirir. Ancak bu ilk yatırım, uygulamanın yaşam döngüsünün 6. ayından itibaren teknik borcu dramatik şekilde düşürerek kendini amorti eder.

Teknik karar vericiler ve mobil mimarlar için karar matrisi şu şekilde özetlenebilir:

  • Küçük Ölçekli / Prototip Projeler: Doğrulama amaçlı MVP (Minimum Viable Product) projelerinde veya ömrü birkaç ay ile sınırlı kampanya uygulamalarında Clean Architecture fazla gelebilir. Standart MVVM mimarisi bu aşamada yeterli çevikliği sağlar.

  • Orta ve Büyük Ölçekli Kurumsal Uygulamalar: Çok sayıda geliştiricinin aynı anda çalıştığı, sürekli yeni özelliklerin eklendiği, kritik finansal veya operasyonel verilerin işlendiği tüm projelerde MVVM + Clean Architecture entegrasyonu standart olarak tercih edilmelidir.

  • Modüler Büyüme (Multi-Module Architecture): Proje büyüdükçe Domain, Data ve Presentation katmanları tek bir uygulama çatısı altından çıkarılıp feature bazlı modüllere (:feature:checkout, :feature:authentication, :domain:checkout, :domain:authentication) bölünmelidir. Clean Architecture, bu tür çoklu modül dönüşümlerine zemin hazırlar.

Doğru yapılandırılmış bir mimari; yazılım ekibine değişen iş gereksinimlerine hızlı uyum sağlama, hatasız kod yayınlama ve platform güncellemelerine kolayca adapte olma gücü kazandırır.

Sıkça Sorulan Sorular

Clean Architecture kullanırken her ekran için mutlaka bir Use Case yazılmalı mıdır?

Hayır, her ekran için Use Case yazmak zorunlu değildir. Eğer ViewModel sadece veriyi doğrudan Repository'den alıp hiçbir iş kuralı veya dönüştürme uygulamadan ekrana basıyorsa, gereksiz kod yükü oluşturmamak adına doğrudan Repository çağrılabilir; ancak karmaşık iş mantıklarında Use Case kullanımı zorunludur.

Domain katmanında Android veya iOS işletim sistemine ait kütüphaneler kullanılabilir mi?

Kesinlikle kullanılmamalıdır. Domain katmanı tamamen saf Kotlin veya Swift kodundan oluşmalı; Android Context, UIKit, SwiftUI veya harici üçüncü parti SDK bağımlılıkları barındırmamalıdır.

DTO ile Domain Entity arasındaki fark nedir ve neden ayrı tanımlanırlar?

DTO (Data Transfer Object) uzak sunucudan veya yerel veri tabanından gelen ham veri yapısını temsil ederken, Entity sadece uygulamanın iş kurallarının ihtiyaç duyduğu saf veriyi barındırır. Backend API değişikliklerinin uygulamanın çekirdek mantığını bozmaması için bu iki model Mapper sınıfları ile birbirinden ayrılır.

MVVM ve Clean Architecture çapraz platform (Flutter, React Native) projelerinde de uygulanabilir mi?

Evet, Clean Architecture ve MVVM prensipleri platform bağımsızdır. Flutter ekosisteminde Bloc veya Riverpod ile, React Native tarafında ise Zustand veya Redux Toolkit kullanılarak aynı katmanlı iş mantığı izolasyonu başarıyla kurgulanabilir.

Clean Architecture uygulamanın çalışma zamanı (runtime) performansını olumsuz etkiler mi?

Katmanlar arası veri dönüşümleri (mapping) ve ek sınıf çağrıları nedeniyle ihmal edilebilir düzeyde mikro-saniyelik bir bellek ve işlemci maliyeti oluşur. Ancak modern mobil cihazlarda bu fark kullanıcı tarafından hissedilmez ve sağladığı bakım avantajının yanında göz ardı edilebilir.

Bağımlılık Enjeksiyonu (Dependency Injection) bu mimaride neden zorunludur?

Dependency Injection, üst katmanların alt katman implementasyonlarına sıkı sıkıya bağlanmasını engeller ve Bağımlılıkların Tersine Çevrilmesi (DIP) kuralını işletir. DI araçları, test ortamında gerçek servisler yerine mock nesnelerin kolayca enjekte edilmesini sağlar.

Repository deseni Data katmanında ne işe yarar?

Repository deseni, verinin nereden getirileceği (REST API, GraphQL, yerel önbellek, SQLite) kararını ViewModel veya Use Case katmanından gizler. Veri erişim mantığını tek bir noktada merkezileştirerek veri kaynakları arasında koordinasyon ve önbellekleme sağlar.

Clean Architecture ile geliştirilen bir projede Unit Test yazmak neden daha kolaydır?

İş mantığı UI bileşenlerinden ve platform bağımlılıklarından tamamen izole edildiği için, testler emülatör veya cihaz gerektirmeden saf test framework'leri ile milisaniyeler içinde çalıştırılabilir ve tüm dış bağımlılıklar kolayca mock'lanabilir.

Son Adım

Dijital projenizi bugün planlayalım

Web, yazılım, e-ticaret, mobil uygulama, entegrasyon, SEO veya GEO ihtiyacınızı net bir kapsama dönüştürelim.

MVVM ve Clean Architecture Mobil Uygulamalarda Nasıl Kullanılır? | Webizm