Skip to content
All posts
June 27, 20263 min read

Clean Architecture in Android — When It Helps and When It Hurts

Clean Architecture is the default recommendation for Android. It's also frequently over-applied. Here's an honest take on when it earns its complexity and when it doesn't.

AndroidArchitectureKotlinEngineering
Share:

Clean Architecture is everywhere in Android. Every tutorial, every sample project, every job posting lists it as a requirement. It's also one of the most over-applied patterns in the ecosystem. Here's an honest breakdown.

What Clean Architecture actually does

It separates concerns into three layers:

  • Data — repositories, data sources, API clients, Room DAOs
  • Domain — use cases, business logic, domain models
  • Presentation — ViewModels, UI state, Compose

The rule: inner layers don't know about outer layers. Domain doesn't import from Data. Presentation doesn't know about Data Sources.

The benefit is testability and replaceability. You can test domain logic without Android infrastructure. You can swap a Retrofit data source for a Room cache without touching the ViewModel.

When it genuinely helps

Apps with complex business logic. If your ViewModel is doing significant data transformation, combining multiple sources, applying rules, or making decisions — a Use Case layer makes that logic testable and clear.

Apps with multiple data sources. Local cache + remote API + real-time updates. A Repository that coordinates these is cleaner than doing it in the ViewModel.

Teams where multiple people touch the same codebase. Clear layer boundaries reduce merge conflicts and make it obvious where new code belongs.

Long-lived apps. After two years of development, a ViewModel that directly calls a Retrofit service is harder to change than one that calls a Repository.

When it hurts

Simple CRUD apps. A screen that shows a list from an API and lets you delete items doesn't need a Use Case. The ViewModel calling the Repository directly is fine. Adding

code
GetItemsUseCase
that does nothing but delegate adds ceremony without value.

Solo projects with tight timelines. Every layer is more files, more interfaces, more boilerplate. For an MVP or experiment, this overhead slows you down.

When the "domain model" is identical to the "data model." If your domain User looks exactly like your API User which looks exactly like your Room User — you're just copying data classes between layers for correctness theater.

The middle path that actually works

For most Android apps, a practical approach:

  1. Always use a Repository. Even for simple apps. It's a single interface between your data sources and the rest of the app. Low overhead, high payoff.

  2. Add Use Cases only when they earn it. If a Use Case contains real logic — transformation, validation, combining sources — it belongs. If it's a one-liner that delegates to a Repository, delete it.

  3. Keep the domain model separate only if you need it. If your API model and UI model are different shapes, a domain model that bridges them is useful. If they're the same, you're adding a mapping step that adds no value.

The question to ask before adding a layer

"If I remove this layer, what breaks?"

If the answer is "nothing, the ViewModel just calls the Repository directly" — the layer isn't earning its place.

If the answer is "the business logic is now scattered across the ViewModel" — the layer is doing real work.

Architecture should reflect the actual complexity of your problem, not an idealized version of what the problem could theoretically become.

After building 22+ apps: I always use Repositories. I add Use Cases when the ViewModel logic gets complicated. I add domain models when the API and UI shapes are genuinely different. Everything else is optional until it's needed.

Share:
S

Sudarshan Chaudhari

AI Systems Builder / Product Engineer

Bangkok, Thailand

Solo Android developer with 13+ years in QA, building Android apps, AI automation systems, and developer tools at SudarshanTechLabs.

Stay updated

Get new posts on Android, Kotlin, and solo dev straight to your inbox.

Newsletter preferences

Related Apps

MyFamilyTracker

Real-time family location sharing — Firebase Realtime DB for sub-second propagation, WorkManager + ForegroundService for OS-compliant background collection, geofencing via Google Maps API.

Building something? Available for Android dev and QA consulting.

Work with me

Comments — powered by Giscus

Apps tagged with this