Bien organiser et structurer son projet est important pour qui ne veut pas se retrouver avec du code spaghetti. On ne se rend compte du problème qu'une fois les mains dans les pâtes. Le code est alors difficile à:

  • maintenir
  • tester
  • débogguer
  • faire évoluer

Dans le courant des idées sur l'architecture des systèmes, Robert C. Martin (aka Uncle Bob), a proposé la clean architecture. La clean architecture est une organisation en couche, chaque couche ayant des responsabilités bien définies. Il convient de noter que la clean architecture n'est pas la solution ultime à toutes vos questions d'architecture. Je trouve néanmoins qu'il est util dans beaucoup de cas, en développement web et mobile notamment.

Dans la suite de cet article, je vais dans un premier temps présenter la clean architecture, puis je vous parlerai de la règle principale de la clean architecture, et je terminerai par ses couches et les interactions entre elles.

Clean Architecture, qu'est-ce que c'est?

La clean architecture est un mode d'organisation, d'architecture, qui met l'accent la séparation des responsabilités, et le découplage des fonctionnalités métiers d'outils comme les frameworks, et les bases de données.

Les objectifs visés par la clean architecture sont les suivants:

  1. Rendre le code indépendant des frameworks
  2. Rendre le code testable
  3. Rendre le code indépendant de l'interface utilisateur
  4. Rendre le code indépendant de la base de données
  5. Rendre le code indépendant des services externes

La clean architecture est résumée par la figure ci-dessous. Dans la suite de cet article, je détaillerai la figure pour bien comprendre le rôle de ses différentes couches.

Clean Architecture
Clean Architecture by Uncle Bob
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

La règle maitresse

La règle qui gouverne la clean architecture est la règle de dépendance. La règle de dépendance stipule qu'une couche inférieure ne doit rien savoir d'une couche supérieure. Les classes, fonctions, variables d'une couche supérieure ne doivent pas être mentionnées dans une couche inférieure. Il ne peut avoir de dépendance que d'une couche supérieure vers une couche inférieure. C'est le sens de la flèche sur la figure.

L'objectif visé ici est simple. S'assurer que les changements apportés aux couches supérieures n'aient aucun impact sur les couches inférieures. On peut donc changer de framework, de base de données, sans avoir à toucher aux fonctionnalités métiers.

Les couches

La clean architecture ne compte pas que quatre couches comme c'est le cas sur la figure. La figure est juste schématique. Selon votre cas d'utilisation vous pouvez avoir plus de quatre couches ou moins.

Entities (Entités)

Une entité est modèle métier de l'application ou du système à construire. Une entité peut être un objet, une structure de données avec des fonctions.

Ex: Un objet, ou une structure utilisateur

Use cases (Cas d'utilisation)

Un cas d'utilisation est une fonctionnalité métier. C'est dans cette couche qu'on implémente les fonctionnalités métiers de l'application.

Interface Adapters (Adaptateurs d'interface)

Cette couche fait la liaison entre les couches supérieures et les couches inférieures. Les adaptateurs convertissent les données dans les formats adaptés aux cas d'utilisation et aux entités. Inversement, les adaptateurs convertissent également les données reçues des cas d'utilisations dans les formats adaptés aux frameworks et autres dépendances externes.  Les opérations de base de données, comme les requêtes SQL par exemple sont implémentées dans cette couche.

Framework and Drivers (Frameworks et Pilotes)

Dans les clean architecture, les outils comme les frameworks, bases de données sont considérés comme des détails. Tout ce qui est lié aux frameworks et dépendances externes est également défini dans cette couche.

Elles interagissent comment les couches?

Les plus observateurs d'entre vous auront remarqué le petit diagramme en bas à droite de la figure. Il explique en guise d'exemple, l'interaction entre un contrôleur de la couche d'adaptateurs d'interface (Interface adapters) et un cas d'utilisation (Use cases).

Rappelons la règle maitresse qui stipule qu'une couche supérieure peut avoir des dépendances dans les couches inférieures, mais pas l'inverse. Un contrôleur peut par exemple avoir un cas d'utilisation comme dépendance mais pas l'inverse.

Dans le cas où une couche inférieure a besoin d'une couche supérieure pour réaliser une tache, un cas d'utilisation qui aurait par exemple besoin de stocker quelque chose dans la base de données, on définit une interface dans la couche inférieure (cas d'utilisation), qui sera implémentée par la couche supérieure (celle de la base de données). On évite alors de créer une dépendance avec la couche supérieure. 

C'est ce qui est illustré par le diagramme en bas en droite de la figure. Le contrôleur dépend du cas d'utilisation, à travers l'interface Use Case Input Port. Cette interface est implémenté par Use Case Interactor qui implémente la fonctionnalité. L'Interactor a aussi besoin du presenter qui appartient à couche du dessus. On crée donc une interface dans la couche cas d'utilisation (Use Case Output Port), dont va dépendre l'interactor. L'interface Use Case Output Port sera implémentée par le presenter dans la couche adapteurs d'interface (Interface adapters). Le presenter sera injecté plus tard dans l'interactor à l'instanciation de l'interactor.

Ce qu'il faut retenir

La clean architecture permet de construire des applications bien structurées, chaque partie ayant un périmètre et un rôle bien défini. Le code est découplé de détails comme les frameworks, les bases de données. Il n'est pas obligatoire d'implémenter toutes les couches de la figure. Il faut néanmoins une couche pour les fonctionnalités métiers (use cases) et une couche pour les adaptateurs d'interface (adapters interface). Des outils comme le framework utilisé ou la base de données, sont des détails. Ils sont situés dans une couche supérieure. Les couches supérieures peuvent avoir des dépendances dans les couches inférieures, mais les couches inférieures ne doivent pas avoir des dépendances, des références dans les couches supérieures. 


Partager cet article

jrgong

Becko Junior Camara

@jrgong

Ingénieur CLoud