clean architecture patterns

Clean Architecture Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "clean architecture patterns" with this command: npx skills add kaakati/rails-enterprise-dev/kaakati-rails-enterprise-dev-clean-architecture-patterns

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

// 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

// 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

// 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

// 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

// 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

// 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

// ❌ 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 } }

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

flutter conventions & best practices

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

getx state management patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

ruby oop patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

rails localization (i18n) - english & arabic

No summary provided by upstream source.

Repository SourceNeeds Review