In this article I’ll explain the code of the Minimal Flutter Bloc App – version of an App that I’m building. Partial snippets you could see here: https://programtom.com/dev/2022/01/07/portfolio-platform-flutter-app-2-code-structure/. The full – working – minimal code you could copy from here: https://github.com/tomavelev/dev_examples/blob/master/bloc/lib_minimal_bloc/main.dart
It’s a lot of times a good idea to complete the whole process of software – vertically with Minimal functionality. When a product delivery is working with no features (including Flutter App), if something breaks the software building process, you’ll know what. It is also a general approach for a minimal viable product development – for reaching the market faster and test if there is a fit for a feature.
Minimal Flutter Bloc App – The Entry Point – main.dart
Every Flutter app has a main method that executes the runApp function with some Flutter Widget. Optionally, before starting the user interface, the developer may initiate some required, global setting or functionality.
The Dependency Injection is a technology that evolved in the back-end systems and has arrived for some years now – to the client side. I’ve personally seen it in
- Java Struts 2 Framework
- Spring Framework
- C# (in my experiments with Xamarin)
- Android Dagger
The Bloc Provider
The provider in itself is a state management option for a Flutter App. In some sense the Bloc & the provider may be viewed as a DI tool for the UI (Builders). The most important goal of DI is separation of concerns that raise up the possibility for testability. It will be easy to mock the depending layers by injecting dummy objects inside the components that return – according to the cases values and functionality.
Any meaningful app has some state beyond the simple display of hard coded – static content. The problem is – where is the data located and how it affects the application. The Statefull Flutter Widgets could hold the data – directly. You could implement optimizations by extracting aside the variable elements and this way a small chunk of the UI will get rebuild. The other way is the information to be delegated to some external to the User Interface component and get build by some Builder Component.
The Problem with Statefull Widget
When a Widget calls the set State method, the system rebuilds the visual tree. This – if repeated a lot – may create a lot of junk, potential performance issues. The whole idea of state management is to detach the state from the widgets, so minimal amount of rebuild is executed.
RX | Streams | Semaphore – Listener Design Pattern
I am not that “fired” with the reactive world, because I’ve seen it’s evolution around 15 years – even before I’ve started coding.
- Java Swing Listeners (in some partial sense)
- Java Streams in Java 8+
- Live Data in Android Architecture Components
- Kotlin Co-Routines
Some of them implement simply the Listener Design Pattern. Others serve as solutions that implement the Semaphore multi-thread problem, resource scarcity and availability and more.
In another philosophically-technical point of view – all the functional – reactive approach makes the code more self-describing. When both the computer and the programmer handle effectively the code – there will be much less bugs in the software. Does it all this – complete its job is another topic.
Events & States
The data of the state is architecturally located in the bloc object. What “view on the data” the Visual layer has on – is wrapped through the bloc states. The User Interface may change the data only through events. And to be in a separate location and also more testable – the rxbloc approach recommends extension methods. (This will be included in a future post for minimalism)