Skip to content

Repository files navigation

Start Learning Clean Architecture πŸš€

Flutter Clean Architecture Learning Journey | Step by Step

I'm sharing my personal journey learning Clean Architecture with Flutter. Every commit is a real step in my learning path.


✨ What I Built So Far

  • Clean Architecture layers (Presentation, Domain, Data)
  • Professional resource management (Colors, Fonts, Themes, Strings, Assets...)
  • MVVM Architecture for OnBoarding Screen
  • Mock API with WireMock
  • Dio + Retrofit setup with code generation + Pretty Dio Logger
  • BaseResponse + multiple typed response models
  • Extension Functions & Mapper extensions
  • Login models in Domain Layer
  • AppServiceClient using Retrofit + Dio
  • Organized Data Layer (network + response folders)
  • RemoteDataSource interface + implementation
  • NetworkInfo interface + implementation
  • Failure class + advanced Error Handler
  • Repository interface + RepositoryImpl
  • BaseUsecase + LoginUsecase
  • App Preferences & Language management
  • Dio Factory improvements

πŸ“Έ Screenshots


πŸ“½οΈ Videos

J.mp4


πŸ“‹ Commits Order (Step by Step)

1. Project setup + clean main.dart
2. Create layers folders (presentation, domain, data, app)
3. Create Application class + Singleton Pattern
4-14. Add Resource Managers (Color, Font, Style, Theme, Route, String, Asset, Constants...)
15. OnBoarding Assets & Strings
16. OnBoarding Screen (first implementation)
17. OnBoarding Screen Refactoring with MVVM
18. Add Dio + Retrofit + json_serializable packages
19. Create BaseResponse class + specific response models
20. Code generation for JSON handling (build_runner)
21. Add the API client class using the retrofit package
22. Create login models to represent the data structure of the response
23. Create extensions functions
24. Create mapper extensions
25. Start implementing the login request
26. Create the remote data source class and remote data source implementation class
27. Add the network info class and network info implementation class
28. Create repository implementation class
29. Add error handler class
30. Enhance error handling
31. Implement Dio factory class
32. Add Pretty Dio Logger
33. Add timeout & language manager
34. Add App Preferences
35. Refactor DioFactory
36. Add BaseUsecase
37. Add LoginUsecase
38. Add LoginViewModel to manage login screen state and interactions
39. enhance LoginViewModel with detailed comments and stream management
40. Implement LoginObject data class and update login view model methods
41. Update LoginViewModel to manage loginObject state and fix stream controller initialization
42. Implement LoginView with ViewModel binding and text field listeners
43. Implement form validation and UI updates based on ViewModel streams
44. register SharedPreferences in dependency injection
45. Register NetworkInfo instance in dependency injection and update LoginViewModel instantiation to use GetIt instance
46. Fix the issue of the login API
---

βœ… Concepts Learned

  • βœ… Clean Architecture Structure
  • βœ… Singleton Pattern
  • βœ… MVVM Architecture
  • βœ… Resource Management
  • βœ… Route Management with RouteGenerator
  • βœ… Mock API with WireMock
  • βœ… Dio + Retrofit + Code Generation
  • βœ… JSON Serialization (json_serializable)
  • βœ… extensions functions
  • βœ… Mapping
  • βœ… Either
  • βœ… Remote Data Source
  • βœ… Error Handler
  • βœ… UseCase
  • βœ… Broadcasting
  • βœ… Data Classes
  • βœ… Dependency Injection

πŸ“ Project Structure

lib/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ app.dart
β”‚   β”œβ”€β”€ constants.dart
β”‚   β”œβ”€β”€ app_prefs.dart
β”‚   β”œβ”€β”€ di.dart
β”‚   └── extensions.dart
β”œβ”€β”€ presentation/
β”‚   β”œβ”€β”€ forgotPassword/
β”‚   β”‚   └──forgot_password.dart
β”‚   β”œβ”€β”€ login/
β”‚   β”‚    β”œβ”€β”€view 
β”‚   β”‚    β”‚  └──login_view.dart
β”‚   β”‚    └──viewModel
β”‚   β”‚        └──login_viewmodel.dart
β”‚   β”œβ”€β”€ main/
β”‚   β”‚    └──main_view.dart
β”‚   β”œβ”€β”€ onBoarding/
β”‚   β”‚   β”œβ”€β”€view/
β”‚   β”‚   β”œ  └──on_boarding_view.dart
β”‚   β”‚   └──viewModel/
β”‚   β”‚      └──on_boarding_viewmodel.dart
β”‚   β”œβ”€β”€ register/
β”‚   β”‚    └──register_view.dart
β”‚   β”œβ”€β”€ resource/
β”‚   β”‚     β”œβ”€β”€ assets_manager.dart
β”‚   β”‚     β”œβ”€β”€ color_manager.dart
β”‚   β”‚     β”œβ”€β”€ constants_manager.dart
β”‚   β”‚     β”œβ”€β”€ language_manager.dart
β”‚   β”‚     β”œβ”€β”€ font_manager.dart
β”‚   β”‚     β”œβ”€β”€ routes_manager.dart
β”‚   β”‚     β”œβ”€β”€ strings_manager.dart
β”‚   β”‚     β”œβ”€β”€ style_manager.dart
β”‚   β”‚     β”œβ”€β”€ theme_manager.dart
β”‚   β”‚     └── values_manager.dart
β”‚   β”œβ”€β”€ splash/
β”‚   β”‚    └── splash_view.dart
β”‚   β”œβ”€β”€ storeDetails/
β”‚   β”‚  └── store_details_view.dart
β”‚   └── common
β”‚      β”œβ”€β”€ freezed_data_classes.dart
β”‚      └── freezed_data_classes.freezed.dart
β”œβ”€β”€ domain/
β”‚    β”œβ”€β”€ models/
β”‚    β”‚  └── models.dart
β”‚    β”œβ”€β”€ repository/
β”‚    β”‚   └── repository.dart   
β”‚    └── usecase/
β”‚       β”œβ”€β”€ base_usecase.dart
β”‚       └── login_usecase.dart
└── data/
    β”œβ”€β”€ network/
    β”‚  β”œβ”€β”€ app_api.dart
    β”‚  β”œβ”€β”€ app_api.g.dart
    β”‚  β”œβ”€β”€ dio_factory.dart
    β”‚  β”œβ”€β”€ failure.dart
    β”‚  β”œβ”€β”€ error_handler.dart
    β”‚  β”œβ”€β”€ network_info.dart
    β”‚  └── requests.dart
    β”œβ”€ response/
    β”‚  β”œβ”€β”€ response.dart
    β”‚  └── response.g.dart
    β”œβ”€β”€ mapper/
    β”‚   └── mapper.dart
    β”œβ”€β”€ data_source/
    β”‚   └── remote_data_source.dart
    └── repository/
       └── repository_impl.dart