Flutter Development through the Clean Architecture Package

A totally new approach to creating a clean flutter development
Flutter Development through the Clean Architecture Package

Flutter is a popular UI framework for developing mobile applications by Google. Flutter’s first release was on Tuesday, December 4, 2018. It has been growing ever since, gaining over 65,000 stars and 7,000 forks on GitHub. It has caught traction in recent years. Sometimes flutter developers have to deal with state management issues in the developing process.

Flutter is composed mainly of widgets [10], which are the basic building blocks of all Flutter applications. A widget can either be stateful or stateless. Stateless widgets have no internal state that can be modified after the widget has been built.

Flutter Development through the Clean Architecture Package
Flutter Clean Architecture Layer Diagram

On the other hand, stateful widgets can be dynamically modified by modifying their internal state without reinitialization. Stateful widgets are important when building any interactive application in Flutter. The Flutter framework creates states for its widgets that can be read synchronously when the widget is built and can be modified throughout the lifecycle of the application. Without proper architecture, managing widget states is very difficult and maintainable.

The fundamental purpose of the architecture is the separation of concerns and scalability.

The Clean Architecture for Flutter should also be highly testable. Due to the complete separation of business logic from the User Interface (UI), Database, and other elements, testing becomes effortless as business rules and UI can be tested. When testing inner layers, dependencies can be easily mocked by inheriting from the abstract classes which are injected into the inner layers.

Example — Authentication-related rules can be tested in isolation from the actual implementation of authentication, whether through an SDK such as AWS Mobile or an HTTP call to an API.

Isolation from External Modules:

In the Clean Architecture, the business layer is at the center of the architecture. The business layer is isolated from the implementation. Therefore, the UI, Database, Web Server, and other elements are outer modules of the application and do not impact the business logic. One major advantage of isolation from external modules is the ability to swap modules with others without impacting the business logic.

Flutter Development through the Clean Architecture Package
Architecture Flow Diagram

Example — An HTTP module that calls an API to retrieve data from a database on a server can be swapped with a local database such as SQLite or an SDK-exposed Database such as Firebase, which would be a far cry from traditional HTTP calls to an API. In the Clean Architecture, outer modules or layers can be swapped without affecting the flow of the application or the business logic.

Clean Architecture can be implemented differently on different platforms. This paper proposes a Flutter-specific implementation designed to fit the structure of Flutter and its inner workings.

Data and Platform Layer:

The data layer is comprised of the data and device subdirectories. In this layer, classes that implement interfaces found in the domain layer are present.

Application Layer:

The application layer is the most framework-dependent layer and is comprised of 3 basic types of classes provided by the Flutter Clean Architecture package. The View class represents only the UI of the page. The View builds the pages’ UI and styles it. It is injected with a Controller class that handles its events through the constructor.

The ViewState uses the Controller, not the other way around. When the ViewState calls a handler from the Controller, it wraps it with a callHandler(fn) function if the ViewState needs to be rebuilt by calling setState() before calling the event-handler. The callHandler(fn) method will handle refreshing the state. Every Controller extends the Controller abstract class, which implements WidgetsBindingObserver.

Every Controller class is responsible for handling lifecycle events for the View and can override —

  1. onInActive()
  2. onPaused()
  3. onResumed()
  4. onSuspending()
  5. onDidPop()
  6. initListeners()

The Controller has a Presenter. The Controller will pass the Repository to the Presenter, which it communicate later with the Usecase. The Controller will specify what listeners the Presenter should call for all success and error events.

Domain Layer:

The Domain layer contains Entities, UseCases, and Repositories. Entities are simple classes, while Repositories are interfaces. On the other hand, UseCases extend the UseCase class provided by the package.

The UseCase is implemented with RxDart and is executed via its public execute() method.

Using the architecture also allowed for easy detection of bugs. Because of the independent layers, bugs in the application were quickly narrowed down to their corresponding layer, where they were easily found by investigating the different components.

Example — Bugs in the application layer were quickly narrowed down to either the Controller or the View.

The implementation of the Clean Architecture through the use of the Flutter Development through the Clean Architecture Package proved to be very effective and advantageous. Combined with ease of testing, the Clean Architecture sped up the development process by maximizing the potential for working in parallel with other programmers.

Read more about this. Let me know your thinking as a response.

One Comment on “Flutter Development through the Clean Architecture Package”

  1. Oh my goodness! Incredible article
    dude! Many thanks, However I am encountering
    issues with your RSS. I don’t understand why I can’t join it.
    Is there anyone else having
    identical RSS problems?
    Anyone who knows the answer can you kindly respond?


Leave a Reply

Your email address will not be published.