Flutter MVVM architecture using Dependency Injection (DI) + State Management + Repository Pattern
When Joe li and I started building NIGHT NIGHT, an app that teaches parents how to make their kids fall asleep by themselves. Me, being the solo developer on this team and coming from a native Android developer background I pondered if I should build it twice using kotlin and learn swift for the iOS version or if I should go for a multi platform solution. Since there was a lot of buzz around flutter, I wanted to see what the fuss was all about.
After only a few hours of doing flutter tutorials, experimenting and watching Flutter Widget of the Week youtube playlist, my speed building UI was already faster and way more enjoyable than native android and I have ~10 years of android experience. That just blew my mind. I was convinced to build this app on it. One month later we released it on the app store and we’re currently getting a great amount of sales.
Here’s my approach to the architecture, for simplification purposes let’s build a simple app that reacts to a login / logout button:
Dependency Injection + State Management
It’s 2020 and if you’re not using a dependency injection library, you might be wasting precious time managing things that could be managed for you. After trying the top 3 recommended libraries for this purpose, I ended up going for provider, a mixture between dependency injection and state management that is pretty straight forward, not very verbose and gets the job done quite well.
Let’s start with our repository, as you can see on the code bellow, we can login, logout and get the current logged in user’s name, if the user kills the app and opens it again it will remember if you’re logged in or not so the UI can change accordingly.
I used https://pub.dev/packages/shared_preferences to read/write to SharedPreferences/NSUserDefaults.
User View Model
This class separates ownership of view data and logic from lifecycle-bound widgets. I talks to the repositories and holds state for your UI to react to.
Simple UI with a login/logout button and a centered text view that change according to the ViewModel state.
Lets make our
asyncso we can initialize all of our components that need to run non synchronous code.
The gift that keeps on giving…
After I started the project, the flutter team released two new features that allowed me, without changing any code, compile to both macOS and web:
All the code can be found here: https://github.com/cesarferreira/flutter-architecture-example
I would love to know what do you think and if you do something in a different way. Also it would be awesome if you click the little clap icon and share the article so more people would benefit from it.