স্কিপ করে মূল কন্টেন্ট এ যান

Architecture Layers বিস্তারিত

Clean Architecture-এ Flutter applications তিনটি প্রধান layer-এ বিভক্ত। প্রতিটি layer-এর নিজস্ব দায়িত্ব এবং structure রয়েছে।

🎯 Domain Layer (Core Business Logic)

Domain Layer হল Clean Architecture-এর হৃদয়। এটি সবচেয়ে inner layer এবং কোনো external dependencies নেই।

📦 Components

🏷 Entities

Business objects যা application-এর core data represent করে।

class User {
final String id;
final String name;
final String email;
final DateTime createdAt;

const User({
required this.id,
required this.name,
required this.email,
required this.createdAt,
});
}

🎯 Use Cases

Specific business operations বা actions। একটি use case একটি নির্দিষ্ট কাজ করে।

class GetUserProfileUseCase {
final UserRepository _repository;

GetUserProfileUseCase(this._repository);

Future<User> call(String userId) async {
return await _repository.getUserById(userId);
}
}

📋 Repository Interfaces

Data layer-এর সাথে communication-এর জন্য abstract contracts।

abstract class UserRepository {
Future<User> getUserById(String id);
Future<List<User>> getAllUsers();
Future<User> createUser(User user);
Future<User> updateUser(User user);
Future<void> deleteUser(String id);
}

✅ Domain Layer-এর নিয়ম

  • কোনো external dependencies নেই
  • শুধুমাত্র Dart core libraries ব্যবহার করে
  • Business logic এবং rules এখানে থাকে
  • UI বা database সম্পর্কে কিছু জানে না

📊 Data Layer (External Data Management)

Data Layer external data sources (API, Database, Cache) থেকে data handle করে।

📦 Components

🏗 Models

API response এবং database entities represent করে। JSON serialization এখানে হয়।


class UserModel with _$UserModel {
const factory UserModel({
required String id,
required String name,
required String email,
required String createdAt,
}) = _UserModel;

factory UserModel.fromJson(Map<String, dynamic> json) =>
_$UserModelFromJson(json);
}

extension UserModelX on UserModel {
User toEntity() {
return User(
id: id,
name: name,
email: email,
createdAt: DateTime.parse(createdAt),
);
}
}

🌐 Data Sources

External APIs বা local databases-এর সাথে communication।

abstract class UserRemoteDataSource {
Future<UserModel> getUserById(String id);
Future<List<UserModel>> getAllUsers();
Future<UserModel> createUser(UserModel user);
}

class UserRemoteDataSourceImpl implements UserRemoteDataSource {
final Dio _dio;

UserRemoteDataSourceImpl(this._dio);


Future<UserModel> getUserById(String id) async {
final response = await _dio.get('/users/$id');
return UserModel.fromJson(response.data);
}
}

🔄 Repository Implementations

Domain layer-এর repository interfaces implement করে।

class UserRepositoryImpl implements UserRepository {
final UserRemoteDataSource _remoteDataSource;
final UserLocalDataSource _localDataSource;

UserRepositoryImpl(this._remoteDataSource, this._localDataSource);


Future<User> getUserById(String id) async {
try {
final userModel = await _remoteDataSource.getUserById(id);
await _localDataSource.cacheUser(userModel);
return userModel.toEntity();
} catch (e) {
final cachedUser = await _localDataSource.getCachedUser(id);
return cachedUser.toEntity();
}
}
}

✅ Data Layer-এর নিয়ম

  • Domain layer-এর interfaces implement করে
  • External dependencies (HTTP, Database) এখানে থাকে
  • Data transformation (Model ↔ Entity) এখানে হয়
  • Error handling এবং caching logic এখানে থাকে

🖥 Presentation Layer (UI & User Interaction)

Presentation Layer user interface এবং user interactions handle করে।

📦 Components

📱 Pages/Screens

UI components যা user দেখে এবং interact করে।

class UserProfilePage extends StatelessWidget {
const UserProfilePage({Key? key}) : super(key: key);


Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Profile')),
body: BlocBuilder<UserProfileBloc, UserProfileState>(
builder: (context, state) {
if (state is UserProfileLoading) {
return Center(child: CircularProgressIndicator());
}

if (state is UserProfileLoaded) {
return UserProfileView(user: state.user);
}

return Center(child: Text('Error loading user'));
},
),
);
}
}

🎮 Controllers/BLoC

State management এবং business logic calls।

GetX Controller:

class UserController extends GetxController {
final GetUserProfileUseCase _getUserProfileUseCase;

UserController(this._getUserProfileUseCase);

final _user = Rx<User?>(null);
final _isLoading = false.obs;

User? get user => _user.value;
bool get isLoading => _isLoading.value;

Future<void> loadUserProfile(String userId) async {
try {
_isLoading.value = true;
final user = await _getUserProfileUseCase(userId);
_user.value = user;
} catch (e) {
Get.snackbar('Error', 'Failed to load user profile');
} finally {
_isLoading.value = false;
}
}
}

BLoC:

class UserProfileBloc extends Bloc<UserProfileEvent, UserProfileState> {
final GetUserProfileUseCase _getUserProfileUseCase;

UserProfileBloc(this._getUserProfileUseCase) : super(UserProfileInitial()) {
on<LoadUserProfile>(_onLoadUserProfile);
}

Future<void> _onLoadUserProfile(
LoadUserProfile event,
Emitter<UserProfileState> emit,
) async {
emit(UserProfileLoading());
try {
final user = await _getUserProfileUseCase(event.userId);
emit(UserProfileLoaded(user));
} catch (e) {
emit(UserProfileError(e.toString()));
}
}
}

🔗 Bindings/Providers

Dependency injection setup।

GetX Binding:

class UserBinding extends Bindings {

void dependencies() {
Get.lazyPut<UserRemoteDataSource>(
() => UserRemoteDataSourceImpl(Get.find()),
);

Get.lazyPut<UserRepository>(
() => UserRepositoryImpl(Get.find(), Get.find()),
);

Get.lazyPut<GetUserProfileUseCase>(
() => GetUserProfileUseCase(Get.find()),
);

Get.lazyPut<UserController>(
() => UserController(Get.find()),
);
}
}

✅ Presentation Layer-এর নিয়ম

  • শুধুমাত্র Domain layer-এর সাথে communicate করে
  • UI state management এখানে হয়
  • User input validation এখানে হয়
  • Navigation logic এখানে থাকে

🔄 Layer Communication Flow

sequenceDiagram
participant UI as 🖥 UI (Page)
participant Controller as 🎮 Controller/BLoC
participant UseCase as 🎯 Use Case
participant Repo as 📋 Repository Interface
participant RepoImpl as 🔄 Repository Impl
participant DataSource as 🌐 Data Source
participant API as 🌍 External API

UI->>Controller: User Action
Controller->>UseCase: Execute Business Logic
UseCase->>Repo: Request Data
RepoImpl->>DataSource: Fetch Data
DataSource->>API: HTTP Request
API-->>DataSource: Response Data
DataSource-->>RepoImpl: Model Data
RepoImpl-->>UseCase: Entity Data
UseCase-->>Controller: Business Result
Controller-->>UI: Update UI State

📚 Next Steps

Layer structure বুঝার পর folder organization দেখুন:


💡 Pro Tip: প্রতিটি layer-এর দায়িত্ব আলাদা রাখুন। Mixing layers হল সবচেয়ে common mistake!