Klassik clean architecture vs Flutter bələdçisi: termin xəritəsi
Flutter dünyasında "clean architecture" ifadəsi iki fərqli şeyi bildirir və bu, çaşqınlığın əsas mənbəyidir.
1. Cəmiyyətdə yayılmış şablon. Hər feature üçün üç qovluq: domain (entity, repository interfeysi, hər əməliyyat üçün ayrı UseCase sinifi), data (model/DTO, data source, repository implementasiyası), presentation (bloc/notifier, səhifə, widget). Xətalar Either<Failure, T> ilə qaytarılır, DI get_it + injectable ilə qurulur. Bu şablon Robert C. Martin-in dörd dairəsindən ilhamlanıb, lakin onun özü deyil.
2. Robert C. Martin-in orijinal prinsipləri. Dörd dairə və asılılıq qaydası. Heç bir qovluq adı, heç bir paket, heç bir UseCase sinif şablonu göstərilmir.
Flutter komandasının rəsmi bələdçisi isə üçüncü, daha yüngül variantdır: iki qat (UI + data), MVVM, opsional domain qatı.
Üçünü də bilmək lazımdır, çünki söhbətdə hansının nəzərdə tutulduğu çox vaxt açıq deyilmir.
| Klassik termin | Flutter bələdçisində | Tipik fayl |
|---|---|---|
| Entity | Domain modeli (model) | `domain/models/product.dart` |
| Use case / interactor | Use-case — opsional qat | `domain/usecases/place_order.dart` |
| Repository (interfeys) | Abstract repository | `domain/repositories/order_repository.dart` |
| Repository implementasiyası | Repository (data qatında) | `data/repositories/order_repository_remote.dart` |
| Remote / local data source | Service | `data/services/order_api_client.dart` |
| Model / DTO | API modeli (ayrı saxlamaq — şərtli tövsiyə) | `data/dto/order_dto.dart` |
| Presentation (bloc/cubit) | View model | `ui/orders/order_list_notifier.dart` |
| `Either<Failure, T>` | `Result<T>` (rəsmi design pattern) | `utils/result.dart` |
| `get_it` + `injectable` | DI — bələdçidə `provider`, bizdə Riverpod | `main.dart` / provider faylları |
| Sual | Cəmiyyət şablonu | Rəsmi Flutter bələdçisi |
|---|---|---|
| Use-case sinifləri | Hər əməliyyat üçün ayrı sinif — məcburi | Opsional; yalnız üç şərtdən biri ödəndikdə |
| Ayrı DTO və domain modeli | Həmişə (model + entity) | Şərtli — böyük tətbiqlərdə tövsiyə olunur |
| Xəta qaytarma üsulu | `Either<Failure, T>` (fpdart və ya dartz) | `Result<T>` — sealed class, Dart-ın öz `switch`-i ilə |
| Qovluq bölgüsü | Feature-first: hər feature-in içində üç qat | Hibrid: UI feature-lərə, data qat üzrə bölünür |
| Boilerplate həcmi | Bir CRUD feature üçün 10-15 fayl | Eyni feature üçün 4-6 fayl |
| Nə vaxt özünü ödəyir | Böyük komanda, uzun ömür, ciddi domain məntiqi | Praktik olaraq hər layihədə |
"Clean architecture istifadə edirsən?" sualına ən güclü cavab şablonun adını deyil, qaydaları saymaqdır: qatlar hansılardır, asılılıq hansı istiqamətə gedir, hansı qat nəyi test edir. Sonra əlavə etmək olar: "use-case-ləri həmişə yazmırıq, çünki rəsmi bələdçi bunu şərtli sayır — bizdə onlar yalnız iki repository birləşdikdə var".
Bu cavab iki şeyi göstərir: prinsipləri anlayırsan və şablonu düşünmədən kopyalamırsan.
Praktika. Öz layihən (ya da GitHub-da tapdığın bir "flutter clean architecture" nümunəsi) üçün yuxarıdaki termin cədvəlini doldur: hansı sinif hansı klassik terminə uyğun gəlir. Hazır sayılır: ən azı 6 sətir dolub və 1-2 termin üçün "bizdə yoxdur, çünki ..." izahı yazılıb.
📚 Mənbələr və sənədlər
- The Clean Architecture (Robert C. Martin)blog.cleancoder.com
Orijinal mənbə — burada nə `UseCase` sinif şablonu, nə `Either`, nə qovluq adı yoxdur. Şablonla prinsipin fərqini görmək üçün oxumaq faydalıdır.
- Flutter arxitektura bələdçisirəsmidocs.flutter.dev
İki qat + opsional domain qatı: rəsmi mövqe.
- Arxitektura tövsiyələrirəsmidocs.flutter.dev
"Conditional" bəndlərin siyahısı — şablonun hansı hissələrinin məcburi olmadığını göstərir.