Clean Architecture Nedir ve Android Projelerinde Neden Önemlidir?

Clean Architecture, Android uygulamalarında kodun modüler ve test edilebilir olmasını sağlarken, uzun vadede projelerin daha sağlam ve sürdürülebilir olmasına olanak tanır. Doğru bir şekilde uygulandığında, Clean Architecture yalnızca geliştirici deneyimini iyileştirmekle kalmaz, aynı zamanda kullanıcılar için daha güvenilir bir uygulama sunar.

 

Bu mimarinin temel amacı, kodun modüler, test edilebilir ve bakımının kolay olmasıdır. Android uygulamalarında, UI, veri işlemleri ve iş mantığı gibi farklı sorumluluklara sahip bileşenleri net bir şekilde ayırır. Bu sayede, her katman yalnızca kendi sorumluluğundan sorumlu olur ve bağımsız olarak test edilebilir.


 

Clean Architecture’ın Ana Prensipleri

Clean Architecture, belirli prensipler üzerine kuruludur:

  • Bağımsız Katmanlar: Katmanlar arasında bağımlılık yönü yalnızca dıştan içe doğru olmalıdır. Örneğin, kullanıcı arayüzü (UI) katmanı iş mantığı katmanına bağımlı olabilir, ancak bunun tersi olmamalıdır.

  • Sorumlulukların Ayrılması: Her katman belirli bir sorumluluğa sahiptir ve bu sorumluluk dışında herhangi bir işlevi yerine getirmez.

  • Bağımlılıkların Ters Çevrilmesi (Dependency Inversion): İş mantığı katmanı (Domain Layer), diğer katmanlara doğrudan bağımlı olmamalıdır. Bunun yerine, arayüzler (interfaces) kullanılarak bağımlılıkların yönetimi sağlanır.

  • Test Edilebilirlik: Katmanların bağımsız olması sayesinde, her bir katman kolayca test edilebilir.

     


 

Clean Architecture’da Katmanlar

Clean Architecture genellikle üç ana katmandan oluşur:

 

 

 

1. Presentation Layer (UI Katmanı)

Bu katman, uygulamanın kullanıcı arayüzünü (UI) ve kullanıcı etkileşimlerini yönetir. UI katmanında genellikle şu bileşenler bulunur:

  • Activity/Fragment/Compose: Kullanıcı arayüzünü oluşturur.

  • ViewModel: UI ile veri katmanı arasında bir köprü görevi görür ve UI durumunu yönetir.

ViewModel Kullanımı:

class MyViewModel(private val useCase: GetDataUseCase) : ViewModel() {
    val data: LiveData<Any> = liveData {
        emit(useCase.execute())
    }
}

Bu yapıda, ViewModel veri işlemlerini başlatır ve UI’yi günceller. Aynı zamanda, yaşam döngüsü değişikliklerine karşı dayanıklı olduğu için, kullanıcı arayüzü durumunu korur.

 

 

2. Domain Layer (İş Mantığı Katmanı)

Bu katman, uygulamanın iş kurallarını ve mantığını içerir. Domain katmanı, uygulamanın en bağımsız katmanıdır ve diğer katmanlardan herhangi bir veri almaz. Bu katmanda genellikle şunlar bulunur:

  • Use Cases (Kullanım Senaryoları): Uygulamanın belirli işlevlerini yerine getirir.

  • Entity (Varlıklar): Uygulamanın temel iş mantığını temsil eden veri modelleridir.

Use Case Kullanımı:

class GetDataUseCase(private val repository: MyRepository) {
    suspend fun execute(): List {
        return repository.getData()
    }
}

Domain katmanının dış bağımlılıkları yoktur ve tamamen test edilebilir bir yapıdadır.

 

 

3. Data Layer (Veri Katmanı)

Bu katman, uygulamanın verilerinin alındığı ve yönetildiği yerdir. Veri katmanında şu bileşenler bulunur:

  • Repository (Depo): Veri kaynaklarına erişimi soyutlar. Repository, veritabanı ve ağ kaynakları gibi farklı veri sağlayıcılarını birleştirir.

  • Data Sources (Veri Kaynakları): Veriler ağdan, yerel veritabanından veya başka bir kaynaktan alınır.

Repository Kullanımı:

class MyRepositoryImpl(
    private val remoteDataSource: RemoteDataSource,
    private val localDataSource: LocalDataSource
) : MyRepository {
    override suspend fun getData(): List {
        return remoteDataSource.getData()
    }
}


 

Clean Architecture’da Bağımlılık Yönetimi

Clean Architecture’da bağımlılıkları yönetmek için Hilt veya Dagger gibi araçlar kullanabilirsiniz. Bu, kodunuzu daha modüler hale getirir ve bağımlılıkların kolayca sağlanmasını sağlar.

Hilt Modülü Örneği:

@InstallIn(SingletonComponent::class)
@Module
class AppModule {
    @Provides
    fun provideRepository(
        remoteDataSource: RemoteDataSource,
        localDataSource: LocalDataSource
    ): MyRepository {
        return MyRepositoryImpl(remoteDataSource, localDataSource)
    }
}

Bu yapı:

  • @Module ve @InstallIn anotasyonları sayesinde Hilt tarafından tanınır.

  • provideRepository fonksiyonu, MyRepository için bir implementasyon sağlar.


     

Clean Architecture Kullanmanın Avantajları

  1. Test Edilebilirlik: Katmanlar bağımsız olduğu için kolayca test edilebilir.

  2. Bakım Kolaylığı: Kodun sorumluluklarının net bir şekilde ayrılması, bakım sürecini kolaylaştırır.

  3. Esneklik: Yeni özellikler kolayca eklenebilir.

  4. Yeniden Kullanılabilirlik: İş mantığı katmanı, diğer projelerde yeniden kullanılabilir.