If you don’t still get what it is, there are many articles out there online and you can go through a couple of them. However, in short, the goal of using clean architecture is to have a codebase:

  1. That does not depend on some framework or library, and
  2. In which business rules (use cases and entities — these are the inner layers of our architecture) do not depend on user-interfaces, databases, web servers, or some external devices (and these are the outer layers).

In other words, dependencies can exist only from outer to inner layers. We put more general stuff in inner layers and are more likely to change stuff in outer layers. As a result, we can easily replace whatever in outer layers easily when we need and without affecting our core logic. And this core logic always stays testable as it’s independent of external factors.


OK, that’s enough for the explanation part! I know these words don’t mean much without showing a real-world example. Therefore, it’s time to get into how I use clean architecture in a Flutter app.

Main project

First of all, our app’s overall architecture is as follows:

Overall architecture of the app

The main/root project has three modules (Flutter packages) in it: presentationdata, and domain. Presentation and data modules are the outer layers of clean architecture, whereas the domain module corresponds to inner layers. That’s why the first two depend on the third one. In the overall picture, our root project depends only on these three packages, nothing else.

In terms of code, the main project has just main.dart file under lib folder. Here, basically what we do is to initialize these three modules and run the app. By initializing, I mean we perform whatever necessary for a module before starting the app; and there might be nothing necessary for some. So, our main function looks something like the following:

void main() {

   //INIT MODULES
   Data.init();
   Domain.init();
   Presentation.init();
   //RUN APP
   runApp(MyApp());
}
class MyApp extends StatelessWidget {
   //...
}

Presentation module

Our first module to talk about is the presentation module. This module directly depends on the domain module in our architecture. It’s not allowed to communicate with the data module. Its package structure is as follows:

Package structure of presentation module

Almost all our code resides in src package. So, presentation.dart, the file which contains Presentation class, decides what to “export”, meaning that it allows what will be visible to the root project.

In src folder, we have the following packages:

  • feature package contains the packages related to all presentational features of the app. As an example, let’s say we have profile feature in our app. So, this package would contain at least the following: ProfilePageProfileControllerProfilePresenter, and a widget package which contains the related widgets used in ProfilePage. I will explain what these classes are responsible for while I’m going through an example. So, please keep reading :)
  • widget package contains the reusable widgets that are not specific to one feature but used by multiple features.
  • core package contains the “brain” of our app, so to speak. It includes all the classes regarding localization, styling, resource/asset handling, page navigation management, constants, etc.
  • entity package contains all simple data classes only related to the presentation layer.
  • util package contains all utility classes only related to the presentation layer.

#flutter #clean-architecture #mobile-app-development

Using Clean Architecture in Flutter
8.20 GEEK