DEV Community

Cover image for Little More Control
Greg Perry
Greg Perry

Posted on • Updated on • Originally published at andrious.Medium

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.

Other Stories by Greg Perry

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.

Design patterns often separate interface, logic and data

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 the 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.

app_view.dart

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.

app_scaffold.dart

categories_controller.dart

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.

categories_controller.dart

recent_pics_controller.dart

top_vids_controller.dart

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.

grid_view_screen.dart

class hierarchy

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:

Which State Management

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.

page_01.dart

page_01.dart

controller.dart

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.

The ‘Little More’ Series

→ Other Stories by Greg Perry

Top comments (0)