Modern Architecture Patterns


1. MVVM Architecture

Q: Explain MVVM architecture and why we use it in Android.

MVVM (Model-View-ViewModel) separates an application into three layers:

Layer Responsibility Android Components
Model Data and business logic Repository, Data Sources, Room, Retrofit
View Display UI, capture user input Activity, Fragment, Composable
ViewModel Hold UI state, expose data to View Jetpack ViewModel

Q: Why is MVVM the recommended pattern?

  1. Separation of Concerns: Each layer has a single responsibility
  2. Testability: ViewModel can be unit tested without Android framework
  3. Lifecycle Awareness: ViewModel survives configuration changes
  4. Maintainability: Changes in one layer don't cascade to others

Q: What are common MVVM mistakes?

  • Passing Activity/Fragment to ViewModel: Causes memory leaks
  • Holding View references in ViewModel: Same leak issue
  • Business logic in View: Should be in ViewModel or Use Cases
  • ViewModel importing android.* packages: Breaks testability (lifecycle components excepted)

Q: What's the Single UI State pattern?

Instead of multiple LiveData/StateFlow for different UI elements, use one sealed class representing all possible screen states. This prevents impossible state combinations and makes reasoning about UI easier.


2. MVI Architecture

Q: Explain MVI and when to use it over MVVM.

MVI (Model-View-Intent) enforces unidirectional data flow:

  • Intent: User actions or events (ButtonClicked, TextChanged)
  • Model: Complete, immutable UI state at any moment
  • View: Renders state, emits intents

The flow is circular: User Action → Intent → Reducer → New State → View Update

Q: MVVM vs MVI comparison?

Aspect MVVM MVI
State Multiple StateFlows Single ViewState
Complexity Lower Higher boilerplate
Predictability Good Excellent (single source of truth)
Debugging Moderate Easy (log all state changes)
Best For Simple-medium apps Complex interactions, forms

Q: When to use MVI?

  • Complex multi-step workflows
  • Forms with interdependent validation
  • Need to track/debug all state changes
  • Time-travel debugging requirements
  • State consistency is critical (financial, healthcare apps)

Q: Describe the layered architecture Google recommends.

Three layers with clear dependencies (outer layers depend on inner):

UI Layer (Presentation)

  • UI elements: Activities, Fragments, Composables
  • State holders: ViewModels
  • Observes state, forwards events

Domain Layer (Optional)

  • Use Cases / Interactors
  • Contains reusable business logic
  • Combines data from multiple repositories

Data Layer

  • Repositories: Single source of truth for each data type
  • Data Sources: Remote (API), Local (Room), Cache

Q: What are the key principles?

  1. Separation of Concerns: UI shouldn't know about data sources
  2. Drive UI from Data Models: UI reflects state, doesn't own it
  3. Single Source of Truth (SSOT): One owner per data type
  4. Unidirectional Data Flow: State flows down, events flow up

Q: When is the Domain layer needed?

  • Business logic reused across multiple ViewModels
  • Complex data transformations or combinations
  • Need to enforce business rules consistently
  • Large teams where clear boundaries help

4. Repository Pattern

Q: What is the Repository pattern and why use it?

Repository is an abstraction over data sources. It:

  • Decides whether to fetch from network or cache
  • Handles caching strategies
  • Transforms DTOs to domain models
  • Provides a clean API to the rest of the app

Q: What caching strategies are common?

Strategy Behavior Use Case
Cache First Return cache, then refresh News feeds, social content
Network First Try network, fallback to cache Critical data, payments
Cache Only Never hit network Offline-first apps
Network Only Never cache Sensitive data

Q: How do you expose data from Repository?

Use Flow for observable data streams. The Room DAO returns Flow, Repository exposes it, ViewModel collects it. Changes propagate automatically from database to UI.


5. Clean Architecture

Q: How does Clean Architecture relate to Android?

Clean Architecture organizes code in concentric circles:

  • Entities (innermost): Business objects, pure Kotlin
  • Use Cases: Application-specific business rules
  • Interface Adapters: ViewModels, Repositories, Presenters
  • Frameworks (outermost): Android, Room, Retrofit

The Dependency Rule: Dependencies point inward. Inner layers know nothing about outer layers.

Q: What are the benefits?

  • Business logic is completely isolated from frameworks
  • Easy to test core logic without Android dependencies
  • Can swap frameworks (e.g., Retrofit → Ktor) without touching business logic
  • Forces clear separation and single responsibility

Q: What are the drawbacks?

  • More boilerplate (mappers, interfaces, multiple models)
  • Can be overkill for simple apps
  • Learning curve for the team
  • Need discipline to maintain boundaries

6. State Management

Q: LiveData vs StateFlow vs SharedFlow?

Type Hot/Cold Lifecycle Aware Initial Value Replay
LiveData Hot Yes (automatic) Optional Latest
StateFlow Hot No (need repeatOnLifecycle) Required Latest
SharedFlow Hot No Not required Configurable

Q: When to use each?

  • LiveData: Simple cases, team familiar with it, automatic lifecycle handling
  • StateFlow: UI state, need .value access, Compose integration
  • SharedFlow: One-time events (navigation, toasts), multiple subscribers

Q: How do you handle one-time events in MVVM?

Options:

  1. Channel + receiveAsFlow(): Consumed exactly once
  2. SharedFlow with replay=0: Events don't replay to new subscribers
  3. Event wrapper class: Wrap value, mark as consumed

Avoid using StateFlow for events—new subscribers receive the last event again.


7. Dependency Injection in Architecture

Q: How does DI fit into the architecture?

DI provides dependencies to each layer:

  • ViewModel receives Repository and Use Cases
  • Repository receives DataSources
  • DataSources receive Retrofit, Room, etc.

This enables:

  • Swapping implementations (real vs fake for testing)
  • Scoping (singleton, per-screen, per-ViewModel)
  • Lazy initialization

Q: What scopes are common in Android DI?

Scope Lifecycle Example
Singleton App lifetime Retrofit, OkHttp, Room Database
Activity/Fragment Screen lifetime Screen-specific analytics
ViewModel ViewModel lifetime Use Cases with state

Quick Reference

Pattern Key Insight
MVVM ViewModel holds UI state, survives config changes, never references View
MVI Single immutable state, unidirectional flow, great for complex UIs
Layered Architecture UI → Domain (optional) → Data; dependencies point inward
Repository Abstracts data sources, handles caching, single source of truth
Clean Architecture Business logic independent of frameworks; more structure, more boilerplate
State Management StateFlow for state, Channel/SharedFlow for events, avoid LiveData for new code

results matching ""

    No results matching ""