UseCase Best Practices (Kotlin / Clean Architecture)
UseCase Best Practices (Kotlin / Clean Architecture)
UseCases (also called Interactors) represent one business action in Clean Architecture.
Well-written UseCases make your app clean, testable, and scalable.
This guide gives you real-world best practices, anti-patterns, and production-ready examples.
1. What Exactly is a UseCase?
A UseCase:
-
Represents ONE user or system action
-
Contains business logic
-
Sits in the Domain layer
-
Is framework-independent
Examples:
-
LoginUser -
GetUsers -
CreateOrder -
UpdateProfile
2. One UseCase = One Responsibility (MOST IMPORTANT)
❌ Bad
✅ Good
💡 Small UseCases are easier to test and reuse
3. Use operator fun invoke()
This makes UseCases readable and expressive.
Usage:
4. Keep UseCases Pure (No Android / UI)
❌ Wrong
✅ Correct
✔ No Context
✔ No ViewModel
✔ No LiveData
5. UseCases Should NOT Know About UI State
❌ Bad
✅ Good
UI mapping belongs to Presentation layer.
6. Use Sealed Result for Errors (Recommended)
UseCase:
7. Do NOT Catch Exceptions Blindly
❌ Bad
✅ Good
Or let repository handle mapping.
8. UseCases Should Be Synchronous in Design
Even though they use suspend, they should feel synchronous.
❌ Avoid callbacks inside UseCases
9. UseCases Can Be Composed
UseCases can call other UseCases.
✔ Reusable logic
✔ Cleaner ViewModel
10. UseCases Should Not Expose Flow Directly (Usually)
❌ Avoid
✅ Prefer
📌 Exception:
-
Streams (location, socket, DB observers)
11. Parameter Object Pattern
Instead of many parameters:
❌ Bad
✅ Good
12. Naming Conventions (Very Important)
Use verb-based names:
✔ GetUsers
✔ UpdateProfile
✔ DeleteItem
❌ UserManager
❌ UserHelper
13. Unit Testing UseCases (Easy & Fast)
14. When NOT to Create a UseCase
❌ Pure UI logic
❌ Simple data mapping
❌ One-line repository calls in small apps
Don’t over-architect
15. Common Anti-Patterns (Avoid)
❌ Fat UseCases
❌ UI logic in UseCases
❌ Repository duplication
❌ UseCase returning DTOs
❌ God UseCase classes
Final Golden Rules
1️⃣ One UseCase = One action
2️⃣ No Android / UI in UseCases
3️⃣ Use invoke()
4️⃣ Keep UseCases small
5️⃣ Test UseCases heavily
Final Summary
-
UseCases are the heart of business logic
-
Good UseCases = clean, testable apps
-
Kotlin syntax makes UseCases elegant
-
Avoid overengineering
