# Flutter Clean Architecture

## Implementing Clean Architecture in Flutter

## Common Issues in App Development

When developing software, especially large-scale projects, you may encounter the following challenges:

* **Difficulty in maintenance**: As the application grows with more features, debugging and fixing issues can become time-consuming.
* **Adding new features**: Implementing new features may affect the application's flow. A proper approach is needed to ensure that adding new functionalities does not significantly impact existing code.
* **Scaling the project**: Large projects with limited resources require well-structured code to allow a single developer to manage multiple parts of the application.
* **Easier collaboration**: Clear and well-structured code makes it easier for team members to hand over or collaborate effectively.

## Why Use Clean Architecture for Flutter?

### Key Benefits – Solving the Issues Above

**Clean Architecture** provides an effective solution for organizing code in a structured manner, offering several key advantages:

* **Increased flexibility**: The most frequently changing components are placed in the outermost layer, making it easier to modify, add new APIs, or access data during maintenance. Features are isolated, allowing team members to develop their parts independently without interfering with others' work.
* **Efficient module management**: Each module is designed separately, making it easy to maintain and expand. Features are placed in distinct directories to ensure they do not affect each other.

### Architecture Structure and My Implementation

* **Domain (Core Logic)**: The innermost layer containing essential business logic, which remains relatively stable.
* **Presentation (UI Layer)**: The middle layer responsible for processing data from the domain and displaying it on the UI.
* **Data (Repository & API Layer)**: The outermost layer, handling API requests and data storage.

#### Core Principles:

* **Inner layers must not depend on outer layers**: The domain layer should not directly fetch data from the presentation or data layers.
* **Outer layers can access inner layers when needed**: The data layer can call domain or presentation layers as required.

## Implementing Clean Architecture in Flutter

<figure><img src="https://2074953091-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F63bX4jdEctx3wiLiur0x%2Fuploads%2FR3w4EqZaWE5QvRrUHLKT%2Fmaintain-and-extend-code-easier-with-clean-architecture-image-1.png?alt=media&#x26;token=90f82d09-de9b-4b03-88a0-ebdd5133de0c" alt=""><figcaption><p>Implementing Clean Architecture in Flutter</p></figcaption></figure>

### Folder Structure

A Flutter project is typically organized as follows:

```
lib/
  ├── features/          # Contains main modules  
  │     ├── module_1/    # Each module follows three layers: Data, Domain, Presentation  
  │     └── module_2/  
  ├── ...  
  └── main.dart          # Application entry point  

```

### Detailed Layer Breakdown

<figure><img src="https://2074953091-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F63bX4jdEctx3wiLiur0x%2Fuploads%2F1OvxNMRdZUoaobNC1cXA%2Fmaintain-and-extend-code-easier-with-clean-architecture-image-2.png?alt=media&#x26;token=5521159f-7f55-436b-84bc-2352a5a76e9e" alt=""><figcaption><p>Detailed Layer Breakdown</p></figcaption></figure>

#### Domain Layer

This is the core layer containing business logic and is rarely modified. It typically includes:

* **Entities**: Core business objects. I have templates for these entities, you can [refer here](https://brickhub.dev/bricks/dr_entity) for using the `json_serializable` plugin or [refer here](https://brickhub.dev/bricks/dr_freezed) for the `freezed` plugin.
* **Use Cases**: Business logic handlers. Some developers omit this folder, considering it unnecessary. However, I find it essential as it clearly defines the use cases for accessing the data layer. It becomes especially useful when combined with system diagrams.
* **Enums**: Enumeration values. I frequently use enums in my projects due to their convenience. You can check out my Mason template for enums at [dr\_enum](https://brickhub.dev/bricks/dr_enum).

**Presentation Layer**

This layer handles UI rendering and user interactions. It typically includes:

* **Views**: Main screens and subcomponents.
* **View Models**: Manages screen states (state management) using libraries like [GetX](https://pub.dev/packages/get), [BLoC](https://bloclibrary.dev/), and [Riverpod](https://riverpod.dev/).
* **Widgets**: Reusable widgets. If you want to create widgets for reuse across multiple projects, consider packaging them. I will cover this in detail in a future article on Flutter packages.

**Data Layer**

This is the most volatile layer, containing repositories for data access. It includes:

* **Constants**: Module-specific constants.
* **Repositories**: Handles data retrieval from APIs or local storage. In the past, I worked with IoT devices using Bluetooth for data exchange, and that logic also belongs to this layer.

### **Automated Structure Generation**

Manually creating folders and files can be time-consuming, especially when setting up new modules. You can use **Mason** to automate this process:

* **Mason** allows you to quickly generate a Clean Architecture structure.
* Reference guide: [Boost your Flutter development efficiency with Mason](https://wongcoupon.com/en/doc/help/flutter/boost-your-flutter-development-efficiency-with-mason).
* Check out the template: [dr\_clean\_arch on Brickhub](https://brickhub.dev/bricks/dr_clean_arch).

## Implementing Clean Architecture in a Project

**Example: PAYMENT Module**

<figure><img src="https://2074953091-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F63bX4jdEctx3wiLiur0x%2Fuploads%2F42vojz46eGRmZ0ZAl654%2Fmaintain-and-extend-code-easier-with-clean-architecture-image-3.png?alt=media&#x26;token=6300be9f-e33c-43bd-a789-13309d83cf9c" alt=""><figcaption><p>Implementing Clean Architecture in a Project</p></figcaption></figure>

### **PAYMENT Module Structure**

```
lib/features/payment/
  ├── data/
  │     ├── repositories/    # Repository handling API data
  │     └── constants/       # Payment-related constants
  ├── domain/
  │     ├── entities/        # Entities for processing data
  │     ├── usecases/        # Core use cases (fetching bills, making payments)
  │     └── enums/           # Enums for payment status
  └── presentation/
        ├── views/           # UI screens
        ├── view_models/     # State management using BLoC/GetX
        └── widgets/         # Reusable widgets

```

### **Component Details**

**Domain**:

* **Entities**: Objects representing invoices, customers.
* **Use Cases**: Functions like payment authentication, retrieving invoice lists.
* **Enums**: Payment statuses (pending, successful, failed).

<figure><img src="https://2074953091-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F63bX4jdEctx3wiLiur0x%2Fuploads%2FjBld01QVCSwEvWTNG11D%2Fmaintain-and-extend-code-easier-with-clean-architecture-image-4.png?alt=media&#x26;token=8510e84c-9c72-4d04-9967-f7fcb1361d1d" alt=""><figcaption><p>Domain</p></figcaption></figure>

**Presentation**:

* **Views**: Displays payment interface and modularized sub-screens for better maintainability.
* **View Models**: Uses BLoC for state management.
* **Widgets**: Reusable buttons and payment-related forms.

<figure><img src="https://2074953091-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F63bX4jdEctx3wiLiur0x%2Fuploads%2Fr5SxjMhp6lmCUGf350hr%2Fmaintain-and-extend-code-easier-with-clean-architecture-image-5.png?alt=media&#x26;token=9c0f8f10-50d0-4cc3-bcf3-6c77ad2d0915" alt=""><figcaption><p>Presentation</p></figcaption></figure>

**Data**:

* **Repositories**: Handles API calls for payments or offline data storage.
* **Constants**: Stores API endpoint configurations.

<figure><img src="https://2074953091-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F63bX4jdEctx3wiLiur0x%2Fuploads%2FiSDJ7wB4XW53mPfd19Ut%2Fmaintain-and-extend-code-easier-with-clean-architecture-image-6.png?alt=media&#x26;token=84634055-3484-4f79-8139-866131b2e9dd" alt=""><figcaption><p>Data</p></figcaption></figure>

## **References**

Here are some useful references I used:

* [Learn more about Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
* [Flutter Clean Architecture Usage](https://pub.dev/packages/flutter_clean_architecture#usage)
* [Clean Architecture with BLoC](https://medium.com/@yamen.abd98/clean-architecture-in-flutter-mvvm-bloc-dio-79b1615530e1)

[Buy Me a Coffee](https://buymeacoffee.com/ducmng12g) | [Support Me on Ko-fi](https://ko-fi.com/I2I81AEJG8)
