Domain, Data, and Presentation layer separation with dependency inversion and use case patterns
Scanned 2/12/2026
Install to Claude Code
npx -y skills add Kaakati/rails-enterprise-dev --skill clean-architecture-patterns --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Clean Architecture Patterns?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/kaakati-clean-architecture-patterns)More formats (shields.io, HTML) on the badges page.
---
name: "Clean Architecture Patterns"
description: "Domain, Data, and Presentation layer separation with dependency inversion and use case patterns"
version: "1.0.0"
---
# Clean Architecture Patterns
## Layer Structure
```
┌─────────────────────────────────────┐
│ PRESENTATION LAYER │
│ (Controllers, Widgets, Bindings) │
├─────────────────────────────────────┤
│ DOMAIN LAYER │
│ (Entities, Use Cases, Interfaces) │
├─────────────────────────────────────┤
│ DATA LAYER │
│ (Models, Repositories, Sources) │
└─────────────────────────────────────┘
```
**Dependency Rule**: Outer layers depend on inner layers, NEVER reverse.
## Domain Layer (Pure Business Logic)
### Entities
```dart
// lib/domain/entities/user.dart
import 'package:equatable/equatable.dart';
class User extends Equatable {
final String id;
final String name;
final String email;
const User({
required this.id,
required this.name,
required this.email,
});
@override
List<Object?> get props => [id, name, email];
}
```
### Repository Interfaces
```dart
// lib/domain/repositories/user_repository.dart
import 'package:dartz/dartz.dart';
import '../../core/errors/failures.dart';
import '../entities/user.dart';
abstract class UserRepository {
Future<Either<Failure, User>> getUser(String id);
Future<Either<Failure, List<User>>> getAllUsers();
Future<Either<Failure, User>> createUser(User user);
}
```
### Use Cases
```dart
// lib/domain/usecases/get_user.dart
import 'package:dartz/dartz.dart';
import '../../core/errors/failures.dart';
import '../entities/user.dart';
import '../repositories/user_repository.dart';
class GetUser {
final UserRepository repository;
GetUser(this.repository);
Future<Either<Failure, User>> call(String id) {
return repository.getUser(id);
}
}
```
## Data Layer (Implementation Details)
### Models
```dart
// lib/data/models/user_model.dart
import '../../domain/entities/user.dart';
class UserModel extends User {
const UserModel({
required super.id,
required super.name,
required super.email,
});
factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'],
name: json['name'],
email: json['email'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'email': email,
};
}
User toEntity() {
return User(id: id, name: name, email: email);
}
}
```
### Repository Implementation
```dart
// lib/data/repositories/user_repository_impl.dart
import 'package:dartz/dartz.dart';
import '../../core/errors/failures.dart';
import '../../core/errors/exceptions.dart';
import '../../domain/entities/user.dart';
import '../../domain/repositories/user_repository.dart';
import '../providers/user_provider.dart';
class UserRepositoryImpl implements UserRepository {
final UserProvider provider;
UserRepositoryImpl(this.provider);
@override
Future<Either<Failure, User>> getUser(String id) async {
try {
final model = await provider.fetchUser(id);
return Right(model.toEntity());
} on ServerException catch (e) {
return Left(ServerFailure(e.message));
}
}
}
```
## Presentation Layer (UI & State Management)
### Controllers
```dart
// lib/presentation/controllers/user_controller.dart
import 'package:get/get.dart';
import '../../domain/usecases/get_user.dart';
class UserController extends GetxController {
final GetUser getUserUseCase;
UserController({required this.getUserUseCase});
final _user = Rx<User?>(null);
User? get user => _user.value;
Future<void> loadUser(String id) async {
final result = await getUserUseCase(id);
result.fold(
(failure) => Get.snackbar('Error', failure.message),
(user) => _user.value = user,
);
}
}
```
## Dependency Inversion
```dart
// ❌ BAD: High-level module depends on low-level module
class UserController {
final UserApiClient apiClient; // Concrete implementation
void loadUser() {
apiClient.fetchUser(); // Direct dependency on implementation
}
}
// ✅ GOOD: Both depend on abstraction
class UserController {
final UserRepository repository; // Abstract interface
void loadUser() {
repository.getUser(); // Depends on abstraction
}
}
```
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!