Domain, Data, and Presentation Layer Boundaries
Separate concerns into entities, repositories, and use cases with strict dependency rules.
Why Layer Boundaries Matter
In a Flutter app of any real size, mixing UI, business rules, and data access into the same files turns every change into a regression risk. Clean Architecture splits the app into three layers:
- Domain — pure business rules: entities and use cases. No Flutter, no HTTP, no Dart packages tied to I/O.
- Data — implements repositories: API clients, databases, DTO mapping.
- Presentation — widgets, state management (Bloc/Riverpod), and view models.
The single most important rule: dependencies point inward. Presentation and Data depend on Domain. Domain depends on nothing.
The Dependency Rule
The Domain layer is the stable core. It must never import from Data or Presentation. Think of it as a circle: arrows of dependency only ever point toward the center.
- Presentation
->Domain (allowed) - Data
->Domain (allowed) - Domain
->Data (forbidden) - Domain
->Presentation (forbidden)
Because Domain owns the repository interfaces (abstractions), the Data layer that implements them depends inward. This is the Dependency Inversion Principle in action.
All lessons in this course
- Domain, Data, and Presentation Layer Boundaries
- Dependency Injection with get_it and injectable
- Feature-First Folder Structure and Melos Monorepos
- Either, Failure Types, and Functional Error Handling