ملخص شامل — Flutter Engineering
Flutter
& Dart
ملخص عملي لـ Flutter Development من الأساسيات لحد الإنتاج: State Management, Clean Architecture, API Integration, Performance, Testing & Release.
UI
→
State
→
UseCase
→
Repository
→
DataSource
→
API / Local DB
// 01 — الأساسيات
Flutter & Dart Basics
Everything is Widget
في Flutter كل حاجة عبارة عن Widget: layout, text, buttons, animations. ده بيخلي بناء الـ UI modular وسهل إعادة الاستخدام.
Stateless vs Stateful
StatelessWidget للـ UI الثابت، و StatefulWidget لما يبقى فيه state بيتغير زي loading, form values, pagination.
Hot Reload
أهم ميزة في Flutter إنها بتسرع التطوير جدًا. بتشوف التغييرات لحظيًا من غير restart كامل للتطبيق.
Dart Null Safety
Null safety بيقلل crash بشكل كبير عن طريق enforce صارم للتعامل مع القيم الـ null أثناء الـ compile time.
Structure سريع لصفحة Flutter
dart
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Dashboard')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Welcome back'),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () {},
child: const Text('Get Started'),
),
],
),
),
);
}
}
/* ———————————————————————— */
// 02 — State Management
State Management
💡 قاعدة مهمة:
اختار state management على حسب حجم المشروع:
- مشروع صغير: Provider/Cubit بسيط
- مشروع متوسط: Cubit + feature modules
- مشروع كبير: BLoC/Cubit + Clean Architecture + DI
Cubit Example
dart
class LoginState {
final bool isLoading;
final String? error;
const LoginState({this.isLoading = false, this.error});
LoginState copyWith({bool? isLoading, String? error}) {
return LoginState(
isLoading: isLoading ?? this.isLoading,
error: error,
);
}
}
class LoginCubit extends Cubit<LoginState> {
final AuthRepository repository;
LoginCubit(this.repository) : super(const LoginState());
Future<void> login({required String email, required String password}) async {
emit(state.copyWith(isLoading: true, error: null));
try {
await repository.login(email: email, password: password);
emit(state.copyWith(isLoading: false));
} catch (e) {
emit(state.copyWith(isLoading: false, error: e.toString()));
}
}
}
/* ———————————————————————— */
// 03 — Architecture
Clean Architecture
Presentation Layer
Widgets + Cubits/BLoCs + UI logic. مسؤول عن عرض البيانات والتفاعل مع المستخدم بس.
Domain Layer
Use cases + entities + repository contracts. ده قلب البزنس logic المستقل عن أي framework.
Data Layer
Repository implementation + remote/local data sources + models/mappers.
Feature Structure
txt
lib/
core/
network/
error/
di/
features/
auth/
data/
datasources/
models/
repositories/
domain/
entities/
repositories/
usecases/
presentation/
cubit/
pages/
widgets/
/* ———————————————————————— */
// 04 — Networking & API
API Integration
Dio Client + Interceptors
dart
class ApiClient {
final Dio dio;
ApiClient(this.dio) {
dio.options.baseUrl = 'https://api.example.com';
dio.options.connectTimeout = const Duration(seconds: 20);
dio.options.receiveTimeout = const Duration(seconds: 20);
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) async {
final token = await getToken();
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
handler.next(options);
},
onError: (error, handler) {
if (error.response?.statusCode == 401) {
// redirect to login or refresh token
}
handler.next(error);
},
),
);
}
}
Repository Pattern
dart
abstract class ProductRepository {
Future<List<Product>> getProducts();
}
class ProductRepositoryImpl implements ProductRepository {
final ProductRemoteDataSource remote;
ProductRepositoryImpl(this.remote);
@override
Future<List<Product>> getProducts() async {
final response = await remote.getProducts();
return response.map(Product.fromJson).toList();
}
}
/* ———————————————————————— */
// 05 — Optimization
Performance Best Practices
Use const Widgets
استخدام const يقلل rebuilds وبالتالي بيحسن الأداء خاصة في الـ widget trees الكبيرة.
Isolates
العمليات الثقيلة (parsing كبير, encryption, image processing) يفضل تتنفذ في isolate بعيد عن main thread.
Dispose Correctly
لازم تعمل dispose للـ controllers والـ streams لتجنب memory leaks مع الوقت.
Image Optimization
استخدم lazy loading + caching + أحجام صور مناسبة لتقليل استهلاك الذاكرة وتسريع الـ rendering.
Compute Example
dart
Future<List<Item>> parseLargeJson(String jsonString) async {
return compute(_parseItems, jsonString);
}
List<Item> _parseItems(String input) {
final decoded = jsonDecode(input) as List;
return decoded.map((e) => Item.fromJson(e)).toList();
}
/* ———————————————————————— */
// 06 — Quality
Testing Strategy
Unit Test Example
dart
void main() {
group('LoginCubit', () {
late LoginCubit cubit;
late MockAuthRepository repository;
setUp(() {
repository = MockAuthRepository();
cubit = LoginCubit(repository);
});
blocTest<LoginCubit, LoginState>(
'emits loading then success',
build: () {
when(() => repository.login(email: any(named: 'email'), password: any(named: 'password')))
.thenAnswer((_) async {});
return cubit;
},
act: (cubit) => cubit.login(email: 'test@mail.com', password: '12345678'),
expect: () => [
const LoginState(isLoading: true),
const LoginState(isLoading: false),
],
);
});
}
اختبار متوازن =
Unit tests (المنطق) + Widget tests (سلوك الواجهة) + Integration tests (رحلة المستخدم الكاملة).
/* ———————————————————————— */
// 07 — Deployment
Build & Release
Release Commands
bash
# Android APK
flutter build apk --release
# Android App Bundle (Google Play)
flutter build appbundle --release
# iOS Release
flutter build ios --release
# Web
flutter build web --release
Checklist قبل النشر
Environment Config
تأكد من مفاتيح production, base URLs, Firebase config, app identifiers.
Signing & Security
تفعيل signing keys، وإخفاء الأسرار في CI/CD secrets، ومنع debug logs.
Crash & Analytics
ربط Crashlytics + Analytics من أول نسخة production لمراقبة الجودة.
CI/CD Pipeline
Automate build/test/release عبر GitHub Actions أو Codemagic لتسريع التسليم.