Explaining Clean Architecture in Flutter Applications [Part 1: Theory] by@andronchik

Explaining Clean Architecture in Flutter Applications [Part 1: Theory]

George Andronchik HackerNoon profile picture

George Andronchik

full-stack engineer and architect

Flutter is a rapidly developing cross-platform framework. It is a truly powerful technology, the state of the art of cross-platform tech. So, let's figure out how to build a good supportable architecture for the Flutter application.

This is the first part of a two-part article dedicated to Flutter Clean Architecture. Today I would like to explain CA theory. This knowledge will help you to deeply understand the second part, where you will implement a CA example.

Clean architecture is a concept outlined by Robert Martin whose main idea is to separate architecture into loosely coupled layers. Thereby we have a good supportable, readable, and testable project.

It is based on these 3 layers:

  • Data Layer: Includes logic of communication with the - database, network APIs, etc.

  • Domain Layer: business logic layer.

  • Presentation Layer: UI.

Data Layer includes Repositories and Data Sources. Data sources implement the logic of data access from different sources (such as network, database, disk, etc). Repositories contain queries and mutations for a specific data model and can decide from which data source gets data (request it from the network or get from cache for example).

Domain Layer contains Models and Use Cases. Models declare data format. Use cases combine data from one or multiple repositories. The Use case is a class where you extract the business logic out of your Presenter/ViewModel. This makes the Presenter/ViewModel simpler because it only coordinates the view and calls Use case. This approach helps to write testable, supportable code.

Presentation Layer contains Views and Presenters / ViewModels (sometimes routers. It depends on the presentation layer architecture you choose). View is what users interact with and coordinated by Presenter / ViewModel which executes one or more Use Cases.

The Presentation Layer always depends on the Domain Layer. Data and Domain can depend on each other and it depends on the variant of implementation.

There are two variants of implementation - Data Flow and Dependency Rule. The main difference between them is that data flow’s domain layer depends on the data layer while the dependency rule’s data layer depends on the domain. I prefer the Dependency Rule and have a couple of reasons for it.


The first reason is that it works with Event Storming and DDD (Domain Driven Design) principles. I mean it is easier to design software driving by domain. Because domain defines business processes and is the most important part of the software.

The second reason is that Flutter is cross-platform technology and it is very important to keep the freedom to use different storage (not only presentations) for different platforms (such as mobile and frontend and desktop in the near future). It is important for any long-term projects, not only cross-platform. But for cross-platform, it is required.

If we designed everything correctly, Domain doesn’t have any dependency on any other layer. Also, a good practice is not to use any external dependencies and frameworks. Try to use clean Dart.

There are some methods to keep the domain-independent from data. Domain Layer includes protocols of repositories, so the data layer only implements it. And we just inject it by DI.

That's it. I hope you like this article. If this part looks difficult, don’t worry, you will understand these conceptions when you see how to realize it. In the second part, we will implement everything you have just read. See you there.

react to story with heart
react to story with light
react to story with boat
react to story with money

Related Stories

. . . comments & more!