Little More Control
A Little More Framework for the Flutter Framework makes for better apps
Part of the ‘Little More’ Series, this article will review how introducing a Controller class to Futter’s State class not only encourages clean architecture but provides a State Management solution to your app.
A Google search of the Flutter website (flutter.dev) highlights the many Widgets and other classes that include the named parameter, controller :
site:flutter.dev insubject:"controller"
In each case, a separate class object assists its host Widget by performing its designated tasks. Delegating work to a separate class mirrors the separation of responsibilities advocated by software design patterns. In this case, this usually involves the decoupling of the app’s interface (view) from its event handling, logic, and business rules (controller). Fluttery uses the [StateX] package because it allows State objects to have their own Controllers.
The Play Store app, [Pexel Preview], uses the Fluttery Framework. Below is a screenshot of that app’s AppState object that defines its general look and behavior (see Little More Adaptive). Highlighted with arrows are its Controllers assigned to perform particular tasks. Again, a State object’s Controllers tend to work the logic while the State object itself with its build() function is more concerned with the interface — a separation of responsibilities is made readily apparent.
Delegate, Delegate, Delegate
In the first screenshot below, the tabs displayed in an example app’s main screen are highlighted with arrows. Each is conceived by the class, GridViewScreen. In the second screenshot below, each is assigned a different Controller object. At a glance, this tells you all three will have the same general appearance while those three different Controllers would suggest there will be three separate and distinct processes going on.
In truth, the only difference between these three Controllers is the data source and the title. Not the best example, but it does demonstrate how a State Object Controller (SOC) allows for this separation of responsibility. Each Controller accesses a different data source (model). You can switch out the data source within the Controller class itself without changing one bit of code on the interface side. This arrangement encourages more modular code. It promotes high cohesion and low coupling — all good attributes to have in software.
Frankly, as seen in the last screenshot above, we can take it further and give no hint at all, on the interface side, what’s involved in those three tabs. Note, how the use of a Controller class also allows for a degree of abstraction. This makes for more adaptive and more robust software.
State Object Controller
You create a SOC by extending the class, StateXController (No relation to the GetXController class). It’s made up of code to reference and work with any and all the State objects it’s assigned to during the app’s lifecycle.
Control The Scope
The Controller class is yours to implement in any fashion you require frankly. For example, taking advantage of object-oriented principals, one Controller class used in the [Pexel Preview] app is actually made up of three other classes. Class hierarchies also tend to make for more adaptive and more scalable software.
Note, how the other areas of the app (its interface and its data) have no idea this hierarchy exists—another characteristic of a clean architecture.
Control The State
Because a ‘Controller’ class is introduced to the State class, Fluttery has introduced a particular architecture — one that assigns distinct ‘roles’ to State objects and their Controllers. In particular, this arrangement allows you to rebuild your app’s interface from outside the Widget tree at any time and from anywhere — a core feature achieved by all State Management solutions.
Call setState() outside the State class anytime, anywhere
The term, State Management, originated from Web developers working with the ‘stateless’ environment that is the HTTP protocol — HTML pages famously did not retain state. State Management came about with the use of Sessions, Client-side cookies, etc. Since Flutter already retains state right out of the box, I would suggest Google took liberties and chose the term to advertise Flutter to the large Web development community.
I’d prefer they didn’t use the term, but they are a for-profit company after all. They want everyone to use Flutter. For Flutter, State Management best refers to the faithful rebuild of the current interface if and when the information displayed in that interface has changed:
Again, the current pile of ‘State Management solutions’ keeps track of the current interface displayed and will rebuild it when appropriate to convey changes. The screenshots below showcase how a State object keeps track of its controllers, and how the controllers themselves can update the interface at any time and from anywhere.
The third screenshot is of Page 2’s controller class, and you can see there are many ways to update that interface. You always have reliable access to a particular State object to rebuild that portion of the screen.
Again, a Controller class is not new to Flutter. The code in the State class involves the interface while the code in the State Object Controller class involves everything else — a proven efficiency yet ‘keeping it Flutter.’
Cheers.