Overview

Clean Framework is a toolkit of classes and implementations that aid developers in creating a layered architecture for any Flutter app, following the principles of Clean Architecture by Uncle Bob (Robert C. Martin).

Understanding the Layers

Clean Architecture is all about separating code into layers to avoid interdependencies and to separate concerns. The following diagram outlines how Clean Architecture proposes implementing different layers.

Clean Framework Layers

The concept of layering an architecture to distinguish domain logic from implementation specifics isn't new, with various methodologies being proposed in the past, such as Hexagonal Architecture. In developing Clean Architecture, Robert Martin has effectively integrated key elements from these existing frameworks, so you may be familiar with some of the terminology.

Here's a quick overview of the different Clean Framework layers:

  1. Entity Layer: This is your app's core. It contains Entity instances that hold your feature's state. These entities are immutable and shouldn't mix with external elements like databases or UI. In Domain Driven Design terms, this would be considered your Domain data.

  2. Use Case Layer: Here's where most of the business logic lives. Use Cases manage the data in Entities and direct data flow. They handle two classes: DomainInput and DomainModel which, similarly to Domain-Driven Design events, move data into or out of the Use Case (respectively). Other layers can only use these components to send and receive data to and from Entities. Being Plain Old Dart Objects (PODOs), Use Cases are completely agnostic to the implementation of outside layers, and can interact with various object types without fussing over details. Use Cases interact with DomainInputs and DomainModels through requests and transformers, which can be either synchronous or subscriptions.

  3. Adapters Layer: This layer translates DomainInputs and DomainModels into specific messages. It includes two main components:

    • Presenters: Presenters turn DomainModels from the Use Case into ViewModels, containing data and behaviors (like callbacks). They handle the UI logic that's not business-related, such as navigation. Presenters subscribe to DomainModels from Use Cases and update the UI with new View Models.
    • Gateways: These handle external data requests to sources such as REST servers, databases, hardware, etc. translating DomainModels into actionable requests. There are two types: a regular Gateway for immediate (synchronous) responses and a WatcherGateway for ongoing subscriptions.
  4. External Interfaces Layer: This layer is where your features interact with external libraries and dependencies. External Interfaces wait for requests to be received from feature Use Cases, which are then processed depending on request type. Clean Framework offers some ready-to-use sub-packages for GraphQL, REST, and Cloud FireStore:

As a side note, the UI layer is considered a type of External Interface layer, as it communicates through an adapter (the Presenter) to exchange state changes with the entities. In the next section, we'll cover the typical structure of a Clean Framework project.