Complete BLoC with Clean Architecture (group chat) Discount !! E-commerce App With Backend Source Code Video and Voice Chatting App Firebase Chatting App Source Code Complete Gym App BLoC State Management Source Code Complete Study App Buy Ticket Booking App Source Code Buy Travel App With Backend Source Code Complete Chat App Udemy Course Special Offer Discount !! Online Learning Course App (BLoC) Online Learning Course App (Riverpod) Online Learning Course App (Getx) Discount !! Shopping App (Provider) Cool Flutter Game Flutter Nodejs Chat App Flutter Nodejs Api And Firebase Chat App Riverpod Task Management App
Clean architecture helps you maintain your code and it's really suitable for large projects and best for scalability. Flutter beginners get difficult time to understand and implement it. And adding BLoC and Cubit with it makes it more difficult. Take a BLoC and TDD with clear architecture course.
Riverpod Clean Architecture Course
This tutorial is not for beginners. You should have at least 6 months experience in Flutter
Here I am gonna explain step by step to understand Clean architecture and also cover TDD at the end. Clean architecture has three layers. This could be your ultimate project or folder structure of Flutter app.
Clean architecture itself follow something called SOLID.
Three layers are Presentation layer
, Domain layer
and Data layer
. Look at the flow them how they are called. The below picture show bidirectional flow of the layer communications.
Domain layer
Domain layer contains the business logic of our application. But this is not BLoC business logic. Strongly suggest to write your code from domain layer.
In general, domain layer works with presentation layer. Domain layer is triggered by an events from presentation layer. These events could be a button press or API calling.
Domain does not depend on anyone. Presentation layer finds domain layer to work with.
First let's a look at this layer and folder structure
Here you can see that have entities
, repos
and usescases
folder. First we should create entities. Entities hold the blue print of our data model which we will pass around for a certain features or screens or pages.
After that we create repository or repos. Repositories contains abstract classes or interface. They are the rules of a particular feature or screen. These classes define what a particular feature should do.
These classes contain methods signature. So the signatue defines what a feature should do.
When presentation layer communicates with domain layer, presentation layer first reach out to usecases folder in domain layer.
From the name it implies that, usecases tells you when to use them. It means what methods are defined there.
Usecases
This sub layer contains tunnel between presentation and domain layer. In general, this is only tunnel between presentation layer and domain layer to communicate.
Here you see how we reached out from our AuthBloc to SignIn class. AuthBloc belongs to presentation layer but it reaches for SignIn class in the usecases folder.
After that usecases reaches to repo which has AuthRepo. AuthRepo is an abstract class and it is implemented by the data layer.
This usecases layer should only contain a class or methods and helper related logic or function.
Usecases layer should be very independent and should not take anything outside of Domain layer.
Data layer
Data layer is for fetching data from outside world to app. Data layer depends on domain layer. If you delete domain layer, data layer will get error. But the opposite is not true. In general data layer contains three below folders.
Since data layer works with external resources and fetch data, it also throws exceptions if necessary. We used dartz package to handle the success or failure.
Data layer contains models, and these models may extend the entities of the domain layer. In our models in data layer we will have toJson, fromJson, copyWith method like these.
What ever is defined in the domain layer repositories, data layer repositories would implement them. So repositories here depend on data source of this layer. Data source would be taken from external server or local storage.
Presentation layer
Presentation layer may include your bloc
, views
, utils
, and widgets
. This layer mostly depends on other layer.
How the layer may look like see the picture below
In general, in widgets
folder you will put the reusable classes or files. Utils
folder contains things like special widgets like styles, colors and things like that.
bloc
folder is the most important one. It contains your state, event and bloc. They are at the heart of the state management.
And views
folder actual screen which the users see. And the classes in this folder connects and contains every other classes in the presentation layer.
Ultimately, views file would contain bloc and bloc itself would contain event and state. The bloc would reach out to domain layer first when an user interaction happens.
The above picture should give you how the views inside presentation layer works. Even though it's one way from the arrow, but it should also work the opposite if you receive data from outside world.
In general the bloc in presentation layer would trigger the usecases of domain layer. And then the usecases would trigger the repositories in domain layer to data layer repository. Remember data layer's repositories are the implementation of the domain layer repositories(they are just abstract classes).
And then data layer's repositories would find the data source and get data back to the usecases of domain layer.
Then domain layer would feed data back to the bloc. And bloc will show the data on the view.
Let's take another look. This might help how you understand the basic flow. The below diagram shows how the basic flow starts from Presentation layer to the domain layer to the data layer. This is uni directional.
Q & A
### Where does the domain layer sit?
==> It sits between data and presentation layer.
### How many sub direcotry does the domain layer have?
==> It will have three sub directories.
### What's the first thing in domain layer?
==> It's the entities folder. It would contain the blue print of the data coming from server. It's like our data structure.
### What does the domain layer's repository do?
==> Repositories contain contract between data layer and domain layer.
### How are the contracts defined?
==> They are defined using interfaces or abstract classes.
### How are domain layers usecases and repository connected?
==> Usescases depend on the repositories.
### What principle does domain layer's usecases follow?
==> They follow SRP(Single Responsibility Principle) principle.
### In TDD, what do you test from the domain layer?
==> We test the usecases of domain layer.
### what else do usecases do?
==> They carry out the operations of repository.
### What are models in data layer?
==> They are like entities with extra features.
### How does domain layer connects to data layer?
==> Domain layer's repos are implemented in data layer.
### What are the repos of data layer?
==> These repos are connected from the repos of the domain layer.
###What is the datasources folder in data layer?
==> Datasources folder's dart files implement the repos of data layer. This is the actual of implementation that's get triggerd from usecases of domain layer.
==> They are the implementation of the domain layer's repo. Domain layer's repos are abstract classes.
### How does presentation layer reaches to domain layer?
==> Presentation layer does it through usecases. Usecases use something called callable() method in dart to reach to the repos of domain layer.
A simple demo of clean architecture
Other BLoC and TDD Clean Architecture related questions are covered here.
SOLID Principle
Clean architecture embodies S-O-L-I-D principle.
Here S stands for Single Responsibility Principle or SRP. Here in every module is responsible for doing only one task. That's why clean architecture has so much code.
Here O stands for Open Close Principle or OCP. It basically means every module or sub layer are open to new extension, which means you can easily add new code without disturbing the architecture.
It means you or your team members should be able to add new functionalities to an existing software system without changing the existing code
L for Liskov Substitution Principle or LSP. It means child class could replace parent class. It's totally object oriented principle. It's about inheritance and getting properties and fields from parent class.
I for Interface Segregation Principle or ISP. It means interfaces are not forced to be used by clients.
D for Dependency Inversion Principle or DIP. It means you should create more interfaces and they should be able to work with new dependency without breaking the old one. It strictly connects with ISP. To follow DIP you must first follow ISP.
We will talk more about S-L-O-I-P in future of this tutorial.