In the scope of this article, I assume that you already know what Clean Architecture is, and why should we use it.
Role and description of each layer:
There is no business logic processing on this layer, hence it is only used to show UI and handle events.
1. Widget (Page)
- Notify BloC of events such as screen display and user touch events, and Listen to the events emitted from BloC as well.
- Receive events from View and execute UseCase according to the event if necessary.
- Emit the data received from UseCase to View.
- BloC doesn’t know about View at all.
This layer is responsible for business logic.
- Describes the logic processing required for the UseCase.
- Work directly to Repository.
- Convert the model into the entity in order to request to server-side, or convert the entity into the model to use for Presentation layer.
- A model will not depend on the data that acquire from server-side.
- A model is used for the Presentation layer.
This layer is responsible for communicating with server-side and data management logic.
- Describes the process to acquire and update the data.
- This is the place decided whether to get the data from the server-side or use the data in the DB or cache.
- An entity will depend on the data that acquire from server-side.
- An entity is not used for the Presentation layer.
- The bridge between Data layer and Domain layer.
- We will use Translator in Repository in order to convert data.
For a better understanding, I’d like to demonstrate a flow that receives an action from Widget, processes it, requests/receives data from the server-side, and finally displays the data to Widget.
1. Data Layer
- Create an Entity.
- Inside api_client_type.dart, define an HTTP request like this:
- Then, open your terminal, and run this command:
make gen, the retrofit will take the rest responsibility. You also can custom the command line by editing this Makefile.
- Define DataSource
- Implement Repository
2. Domain Layer
- Create Model
- Define Translator
- Implement UseCase
3. Presentation Layer
- Define BloC
- Implement Widget
Let’s make our code becomes more modular. 😎
- Create config_module
- Create client_module
- Create datasource_module
- Create repository_module
- Create usecase_module
- Inject UseCase to BloC in my_app.dart by conforming to all of the modules.
That’s all, run the project, and let’s see what happens!
In order to run this project, you need to run in a specific environment.
flutter run -t lib/main_dev.dart
flutter run -t lib/main_prod.dart