Clean Architecture - Flutter
Clean Architecture — Every one talks about this but very few implement it.
But if you need to implement it, there are different approaches based on different developers but the core concept is always the same.
Divide your code/logic based on layers.
But they only talk inward not outward. Means if you need to talk someone you can only the people under you not the ones above you.
If you need to learn the basic and each terminology can go this link. Every architecture is interpreted by different developers differently and there is no wrong answer but only less correct answer.
So, here is one approach from my end, feel free to give your feedback. Might help someone to understand better or improve or correct my understanding of this architecture.
- Application layer
- Domain layer
- Data and Device layer
Only three I think would be enough for a project. But can grow depending on how you are going to divide your project.
The UI layer basically, which is shown to the user basically.
Now, what you should add into this layer,
- naviagtors : Which will contains the navigation routes. If needed to move to a different page should be done from here. Since different developers use different approach for navigation, so inside classes may differ. I prefer GetX for navigating, because it’s easy 😁.
- pages : Pages are like different screens for your application like Splash, Home, Profile, etc.
- theme : Contains all the theme related code for your application like styles, custom colours, dimensions.
- utils : Your utility classes. The common codes should be dumped here. You know, for reusability.
- widgets : Custom common widgets can we used any where in the application layer.
Will take an example for splash screen,
You can ignore the splash_binding.dart file. If you have worked on GetX then you would know what that file is doing.
- Controller : Which will update the UI. State management will be done from controller.
- Presenter : A sub-layer you can say which will connect the application layer to the other layers through use cases.
- View : Your view code.
So this is like the basic folder structure of your application layer. Now keep in mind before going to the next layer,
View talk to controller and controller talk to presenter. Presenter get the data and give it to the controller and it updates the UI. Presenter doesn't know from where it got the data.
The layer which gives data to the Presenter layer is the Domain layer. It’s like an intermediate layer between application and other layers. But the one which Presenter talks to are the use cases.
Use cases are like set of common functionality which will be done in the data and device layer. Like user related work for example sign in, sign up, get user details and so on but only related to user and local use cases like save data or fetch the data from device and so on. It depends on the developer how the use cases must be divided.
And uses cases connects with the Domain layer and the Presenter of the Application layer and talk to each other. But use cases doesn’t have their own brain so they use the brain of Domain layer and talk to Presenter.
Domain layer has only this concept. It has the device and data layer dependencies through which it talks to both of them.
- entities : These are the model classes basically or the enums and all.
- repositories : These are ones which will fetch the data from Data and Device layer.
- services : There are some time when you need to do some common services like connectivity check and all or permission handling. So these all can be added in services.
- usecases : The mutual friend between Application layer and Domain layer.
Data and Device Layer
These both layers are actually same but the places from which they get the data are different.
Device layer fetches the data from local storage.
Data layer fetches the data remotely like from you backend.
For Data Layer,
- helpers : These are like http or your dio classes.
- repositories : These are the ones which get the data from remote using the helpers.
For Device Layer,
- repositories : These are the ones which get the data from the local storage.
Now, I know if you are new to this you are sill confuse, so let me show you are design which might help you understand things in a more simpler manner,
So, the talking always starts from Application Layer. He is like your best friend. Now Application layer wants to update the View. So it tells the Controller that I want the user name of the current one which is saved locally after successful login.
So, it sends a request to Controller. But Controller doesn’t have that information currently. So a request from Controller to the Presenter is send.
But the funny thing is Presenter doesn’t have a mind of his own. But due to his/her smartness he/she doesn’t let the Controller know about it.
Since the user name is saved locally so Presenter ask the Local Usecases that can you share me the user name which might be saved in the device local storage.
Local Usecases is also same like Presenter with no brain. He/She asks the Domain layer that can you find the user name and send it to me.
Now, Domain layer asks first the Device Layer because its fast and if he/she has the data it will be send immediately instead of waiting. And the best part was the Device layer has the user name. So it returns to the Domain layer telling the user name last saved locally was “Pradyot Prakash”.
Now Domain layer has the user name so like a good friend he/she returns the name back to the Local Usecases. And similarly the data is returned back to the Presenter which was waiting for Local Usecases.
And after getting the user name, Presenter gives it to the Controller and the UI is updated.
🤯 — If you are not like this then congratulations. You can now divide your code based on layers.
Understanding these kind of architecture is always hard, but once you do understand it and start implementing it, your development would be more easy.
Now, there might be a question like how I came or understood to this structure. And I am like a Common Developer and you should never underestimate the power of a Common Developer 😜.
No, but I learned it from a pub packaged which is flutter_clean_architecture. It’s a package so you can use it directly but instead I only took the folder structure of how they are organising the files and layers. Which you can see below.
You can read that package README. They have explained I think everything there.
Its hard but fun to work in an organise way. Once you get used to it then its a matter of time you will be structuring your all projects like this or the ones which you like.
I liked it so I am using it. Do what you feel like because that’s what make development fun and exciting 😎.
Flutter : Love at first build.