Design patterns & Clean architecture in flutter - flutter

When I start programming a new application in flutter everything goes well at the beginning but when the project grows up it starts to become messy, and then I decide to delete the project to start over.
I searched about the clean architecture and design patterns but I found a lot of choices such as DDD, BLoC, and so many patterns and architectures, I didn't what is the best thing to stick with every time I enter a research process that lasts forever.
So I want to hear from you as professionals and expert coders what is the best thing to stick with and what should I do? please give some advice on how to deal with big projects in flutter?
Thank you very much

Firstly the Flutter project architecture is very subjective because it depends on your needs.
But we can find some general principles:
Use a router system : By default flutter provide a Navigator API to let you navigate through your app. But there is no real structure and when you want to use push notifications to redirect the user to your App you will be stuck.
GoRouter package delivers a very nice router system, and Google teams are thinking about implementing it into the Flutter SDK.
Take advantage of a StateManagement library : When your application will become bigger you will want to handle the state of the app more precisely. So you will be able to refresh and update the content of pages easily and without reloading the content. To do that there are a lot of packages :
BLoC
Provider
Cubit
GetX
Handle the data (like API JSON Response, or SQLite Query). A huge part of a clean architecture is the way you manage the data. If you use an API you have to deal with JSON Serialization. In a small app you can do your own system to deserialize data, but you have to implement a lot of boilerplate code. I recommend to use build_runner and json_serializable packages. This stack of plugins lets you build your data classes easily without worrying about the serialization : BuildRunner will generate this code for you.
Use a structured folder system. Personally I used the DDD pattern, because you can easily separate your data from the logic of your app, this improves your maintainability.
Schema of a Flutter Clean Architecture with DDD
I hope this will help you to develop your own architecture. To wrap up, here are some helpful resources on this topic.
https://devmuaz.medium.com/flutter-clean-architecture-series-part-1-d2d4c2e75c47
https://docs.flutter.dev/development/data-and-backend/json
https://codewithandrea.com/articles/flutter-project-structure/

It's a good idea to choose layer-first or feature-first approach for your project as step one. Mentioned link to Andrea's article is a great one - https://codewithandrea.com/articles/flutter-project-structure/
Then you choose whether you want to use Riverpod with providers or blocs and/or cubits. You can write an app with all of them, so I would recommend to try them first and then make a choice. For example, I wrote a Flutter app using cubits only.
Next, you can choose routing library, to make life easier with navigating to/from screens, deep linking etc. Either auto_route or go_router is good.
Also, make use of libraries for json serialization, data classes, injectables, as they save you from lots of boilerplate code.

Related

What is the best design pattern between BLoC, MVVM, MVC for Flutter app?

I'm going to develop a management app for a company in Flutter and since I never worked with this framework i was looking for the best practices and desin patterns to use.
The app will be about employes management for a company. The main features will be:
The management of the employes profiles;
The possibility to upload documents directly in the app;
Create online quiz for the employes in trainership;
I'm struggling to choose the right design pattern. Usually for the frontend i use either the MVC or MVVM, but since this is my first Flutter app i made some researches and find out that one of the best pattern for Flutter is BLoC. I already tried to implement a simple app to try this pattern and i understood the way it works, but since I'm a noob in Flutter i was looking for some advices from someon who is more expert than me.
Thank you in advance for the help.
the best practices and design patterns to use it is TTD
it helps you to Keeping your code clean and tested
on the other hand, larger projects start falling apart when you mix the business logic everywhere. Even state management patterns like BLoC are not sufficient in themselves to allow for easily extendable codebase.
to get more information about TTD you can look to this tutorial in this link : https://resocoder.com/2019/08/27/flutter-tdd-clean-architecture-course-1-explanation-project-structure/

Flutter: State management

I've seen many tutorials praising Bloc State management, what is so special about it and should I learn it as a beginner? if not is there any beginner friendly state management technique?
BLoC/Cubit
BLoC is great for complex state management for complex apps. However, inside the BLoC library there's a simpler way of managing state that's called Cubit (Cubit is sort of a subset of BLoC). Cubit is largely the same as BLoC except:
less boilerplate
doesn't use 2-way streams
This renders it much easier to learn, and a fantastic stepping-stone into a full-out BLoC driven state management solution.
Currently, my team and I are building a very complex app, and we use the principle: use Cubit's, unless there's a specific reason to use a BLoC. This has worked well for us (85% of our app is run with Cubit, 15% with BLoC).
In relation to other state management techniques, most people are probably going to recommend Provider or Riverpods (Riverpods = Provider on steroids). They are easier to learn than Cubit/BLoC. Except, only for simple cases (a few page app). Once your app gets complex (authentication, feeds, api calls, etc.) a Cubit/BLoC-based architecture is going to scale better and be much cleaner.
Additionally, the most-used state management system for production-level Flutter apps is BLoC/Cubit. So, if you're looking for a marketable skill, I'd default to that.
Helpful links:
Flutter package that contains BOTH BLoC and Cubit.
The tutorial series I watched to learn BLoC/Cubit (and recommend!).
I HIGHLY recommend watching this series as well that shows WHERE to put your BLoC/Cubit in an app to align with best practices and clean architecture.
Example app (understanding this will help you a lot):
Here's a simple 1-feature app I made as a proof of concept to show how Cubit specifically works. Read the project's README.md for context.
Conclusion:
Provider, GetX, Riverpods, etc. are all easier to learn and contain less boilerplate than BLoC, except they won't scale as well when your app gets more complex.
To help combat the boilerplate/complexity problem of BLoC, use Cubits instead of BLoCs in your design unless you have a specific need for BLoCs.
Cubits are quite easy to understand and can be used in most of the Flutter projects. For bigger apps I would go for Riverpod. Having independent providers gives a lot of flexibility, as they can be used in different parts of the app and you can make any future, use case or repository a provider.
I have wrote a tutorial with Flutter app on how to write a List - Details app using cubits, hooks and local database with Hive.
GETX - State Management
I would suggest Getx as I have been using it for 3 years and it's incredible.
It is effortless to learn.
I never encountered a need to use any other state management.
Features provided by GETX
State management
Dependency Injection
Theming
Clean Structure
Internationalization
Validation / Utils
Documentation

Best Practices in Flutter/Dart and Clean Architecture (maintaining separation of concerns between data, domain and presentation layers)

I'm a backend developer with background of Java and Python. I've started with Flutter 3 months ago. I find Dart an easy language to learn and fun to write code in. Google did a good job there.
What is challenging for me is figuring out best practices when working with flutter. The official documentation (docs.flutter.dev) is good and it's also interesting to look at the Dart code powering the framework. But I haven't seen a resource that goes over best practices for design/architecture of a Flutter application.
In particular, I'm interested in how to maintain separation of concerns between Database , Domain and Presentation layers.
I'm using Firebase Store for my (realtime) database. The API provides the data in the form of a JSON object (Map). This is fine, but I want to translate this into my own domain model instances (for data validation, enrichment and enforcing other business rules). What I don't know is how to bridge the gap between database and UI (Widgets). I want to keep a Clean Architecture, and would like to learn how to do this correctly. I should also add that I don't have prior experience with Asynchronous code, which seems to be an important skill to gain.
I've experimented in using InheritedWidgets to try and expose my data to the UI/Presentation layer as model instances, without the UI knowing about the specifics of the database, but ran into difficulties because I don't understand the Flutter framework and Dart async programming very well. I also know there are frameworks like Bloc that are supposed to solve data/state management issues. But as much as possible I want to stick to the basics before I start using more elaborate and heavier tools.
What recommended resources are out there that I'm missing, that could help me become a better Dart/Flutter developer?

Flutter state management without BLoC

my question is about what approach to choose for app state management. Many walktrough talks about BLoC, RxDart, Redux etc.
My aim is to develop a simple app that download sometimes data from a server and keep using local storage (SQL in flutter) to handle the data (CRUD operations). Other involve few user data handled by shared preferences.
I don't need high performance / super asynchronous stream of data from a server(as shown in 90% of tutoral of BLoC logic).
Is truly neecessary to have an app state pattern and what can the best approach for my case?
Yes, BLoC, RxDart, Redux are good enough.
But we should choose the things on our requirement and here in this project, there is no need to use any three of these.
For state-management, you can use the provider package as this suits best to your requirement, and it's easy to use and implement
A very simple example to implement it is here
You can use the approach of Stateful Widgets, and do your process (in case you do not need a app with a high performance), but the best approach I would suggest is to use PROVIDERS, they are easy to implement, You can take care of the downloading process and the saving also in a easier and cleaner manner, the App will perform very well, and also works well with Stateless widgets (you can rebuild only the necessary parts in a complex widget tree).
But have your own research, and find out which will suit your App the best,
Happy Coding :)
My suggestion is to try to use a mix between Provider and BLoC, instead of using RxDart, Redux which requires too much boilerplate code and it is more used to manage streams.
The provider will allow you to share information between your widget tree, in an organized way and BLoC will help you to separate your logic from your UI, the best practice to grow in time.
I suggest content from this channel: https://codewithandrea.com/tags/provider/ He helps and provides good resources to implement an easy and understandable architecture background.

Which one is faster and performant Provider, bloc pattern or flutter_redux?

I need manage the states globally, I find a lot of way, in terms of managing the state by using Provider bloc pattern redux and etc.
But actually I dont know, which one is faster and performant?
Example: I am working on chat application, which I have to manage socket connection messages online offline status all as globally. the states need to be accessible from all screen, like ChatList screen, ChatBox screen and more...
I didn't test them all performance wise. And i do not think it will make much of a difference.
Provider works with inheritedwidget as scoped model i think.
I love the streams for the versatility of the data flow.... i think the key part for performance is to keep the rebuilding/painting of the widgets that require it at the lowest level of the tree.
get_it package should help you to keep those streams accessible everywhere, is a great simple package to keep neat model access, regarding the state management solution.
For instance, i believe that generating statelessstateful widgets instead of functions that returns widgets to make the layout, provides more performance, for the separation of buildcontexts.
In any case, the framework is super optimized and performant... if u run into any issue, u can easily track it down with the devtools and the community is very supportive.
Btw, take my basic reply with a grain of salt, as I've been only playing with flutter/dart for a week.