// Architecture Logicielle — Détail

Architecture Layered
N-Tier / En Couches

L’architecture la plus répandue dans l’industrie — et la plus mal comprise. Séparation horizontale des responsabilités, mais attention aux pièges que pointe Uncle Bob.

01

La métaphore : le restaurant gastronomique

🍽️

Chaque brigade a son rôle — et ne touche pas aux autres

Imagine un restaurant gastronomique. La salle accueille les clients et prend les commandes — c’est la couche de Présentation. Le chef en cuisine décide des recettes, des temps de cuisson, de l’assaisonnement — c’est la couche de Logique Métier. Le garde-manger gère les stocks, les commandes fournisseurs, le rangement — c’est la couche d’Accès aux Données. Et la chambre froide stocke les ingrédients bruts — c’est la Base de Données.

Le serveur ne va jamais directement en chambre froide. Il passe par le chef, qui passe par le garde-manger. Chacun a sa responsabilité, et les dépendances ne s’écoulent que dans un seul sens — du haut vers le bas.

Si le restaurant change de fournisseur de viande (la base de données change), le chef adapte peut-être ses recettes, mais le serveur ne le sait même pas. Et si un client veut commander en japonais au lieu de français (changement d’UI), la cuisine ne change rien.

02

Les 4 couches fondamentales

L’architecture Layered organise le code en couches horizontales empilées. Chaque couche a une responsabilité unique et ne communique qu’avec la couche immédiatement inférieure. C’est la séparation des préoccupations la plus intuitive qui existe.

Layer 01
🖥️
Presentation Layer — Couche de Présentation
Interface avec l’utilisateur. Reçoit les requêtes, affiche les réponses. Ne contient aucune logique métier.
HTML / CSSReact / VueREST ControllersGraphQL ResolversCLIMVC Views
appelle
Layer 02
⚙️
Business Logic Layer — Couche Métier (BLL)
Le cœur du système. Contient les règles métier, les calculs, les validations et les workflows. Ne connaît ni l’UI ni la base de données.
ServicesUse CasesValidatorsDomain ObjectsWorkflow Engine
appelle
Layer 03
📂
Data Access Layer — Couche d’Accès aux Données (DAL)
Abstraction de la persistance. Expose des méthodes CRUD simples à la couche métier. Cache les détails SQL, ORM et requêtes.
RepositoryDAOORM (TypeORM / Hibernate)Query BuilderCache
appelle
Layer 04
🗄️
Database Layer — Couche de Persistance
Le stockage des données. SQL, NoSQL, fichiers, services externes. Ne contient aucune logique applicative — uniquement des données.
PostgreSQLMySQLMongoDBRedisS3Elasticsearch
Règle fondamentale : Les dépendances ne s’écoulent que dans un seul sens — de la couche haute vers la couche basse. La couche N peut appeler la couche N-1, jamais la couche N+1.
03

Flux d’une requête — du navigateur à la DB

Suivons une requête POST /orders de bout en bout, couche par couche. Chaque étape montre comment la responsabilité est déléguée vers le bas — et comment la réponse remonte.

🖱️ POST /orders — Requête HTTP du navigateur Le Controller reçoit la requête et la valide
appelle
⚙️ OrderService.createOrder(dto) Vérifie le stock, applique les remises, calcule la TVA
appelle
📂 OrderRepository.save(order) Traduit l’entité en SQL INSERT, gère la transaction
exécute
🗄️ INSERT INTO orders VALUES (...) PostgreSQL persiste l’enregistrement
retour
✅ HTTP 201 — { orderId: "abc-123", status: "confirmed" } La réponse remonte couche par couche
04

Structure concrète — TypeScript / NestJS

Voici comment les 4 couches se traduisent en une structure de fichiers concrète dans un projet TypeScript avec NestJS. Chaque dossier correspond à une couche, et les dépendances ne pointent que vers le bas.

src/ ├── presentation/ ← Couche 01 — Controllers, DTOs, Middlewares │ ├── controllers/ │ │ └── OrderController.ts // POST /orders → appelle OrderService │ ├── dto/ │ │ ├── CreateOrderDto.ts // Validation des inputs (class-validator) │ │ └── OrderResponseDto.ts // Shape de la réponse JSON │ └── middlewares/ │ └── AuthMiddleware.ts // JWT guard├── business/ ← Couche 02 — Règles métier pures │ ├── services/ │ │ └── OrderService.ts // createOrder() — orchestration métier │ ├── entities/ │ │ └── Order.ts // Entité métier (pas un entity TypeORM ici) │ └── validators/ │ └── StockValidator.ts // "Le stock est-il suffisant ?"├── data-access/ ← Couche 03 — Accès aux données │ ├── repositories/ │ │ ├── OrderRepository.ts // save() findById() findByUser() │ │ └── ProductRepository.ts // findById() decrementStock() │ └── entities/ │ └── OrderEntity.ts // @Entity() TypeORM — mapping DB└── database/ ← Couche 04 — Config DB, migrations ├── migrations/ │ └── 001_create_orders.ts └── database.module.ts // TypeORM config, connection pool
05

La critique d’Uncle Bob — le piège du schéma DB

📖

Robert C. Martin — Clean Architecture (2017)

« Les détails doivent dépendre des politiques, jamais l’inverse. Dans une architecture en couches classique, la couche métier dépend directement de la couche d’accès aux données — ce qui signifie que le schéma de la base de données dicte la structure des entités métier. C’est exactement l’inverse de ce qu’il faudrait. »

Dans une architecture Layered classique, les dépendances pointent vers le bas : la Présentation dépend du Métier, qui dépend de l’Accès aux Données, qui dépend de la Database. Le problème ? La couche la plus volatile (la DB) se retrouve à la base de tout le système.

Presentation
dépend de
Business
dépend de
Data Access
dépend de
Database

⚠️ Le problème concret

Si le DBA modifie une colonne dans la table orders, le changement cascade à travers toutes les couches : l’entity ORM change, le repository change, le service change, le DTO change, le controller change. Une modification de détail technique (la DB) force une modification de politique métier — exactement ce qu’Uncle Bob interdit.

La solution d’Uncle Bob ? L’inversion de dépendance (DIP). La couche métier ne dépend plus de la couche d’accès aux données — elle définit une interface que la couche DAL viendra implémenter. C’est le principe fondateur de la Clean Architecture, de l’Hexagonale, et de l’Onion Architecture.

06

Variantes — 2-Tier, 3-Tier, N-Tier

🟠
2-Tier
Client — Serveur
L’application est divisée en deux parties : un client lourd (desktop, WinForms) qui contient la logique métier et la présentation, et un serveur de base de données qui gère la persistance. Les stored procedures vivent côté serveur. Simple mais couplage fort entre UI et métier.
LegacyDesktop AppsStored Procs
🟢
3-Tier
Présentation — Métier — Données
Le modèle le plus répandu. Un serveur web (présentation), un serveur applicatif (logique métier) et un serveur de données. Chaque tier peut être déployé sur une machine séparée. C’est le standard de l’industrie depuis les années 2000.
Web classiqueJava EEASP.NETPHP MVC
🟣
N-Tier
Extension à N couches
Au-delà de 3 couches : on ajoute une couche de services (API Gateway, orchestration), une couche d’intégration (messaging, ESB) ou une couche de cache. Chaque couche supplémentaire ajoute de l’abstraction — et de l’indirection.
EnterpriseService LayerIntegrationCache Layer
🔵
Strict vs Relaxed
Layered strict ou ouvert
En mode strict, chaque couche ne peut appeler que la couche immédiatement inférieure (N → N-1). En mode relaxed, une couche peut sauter des niveaux (Présentation → DAL directement). Le pragmatisme impose souvent un mix des deux.
StrictRelaxedPragmatisme
07

Avantages & Limites — Bilan objectif

CritèreÉvaluationCommentaire
Compréhension✓ ExcellentTout développeur comprend instinctivement la séparation en couches. Pas besoin de formation spécifique.
Séparation des concerns✓ BonChaque couche a un rôle défini. La présentation ne touche pas la DB, la DB ne connaît pas l’UI.
Testabilité~ MoyenLa couche Business est testable si elle ne dépend que d’interfaces. Souvent, elle dépend directement du DAL concret.
Évolutivité~ MoyenFacile d’ajouter des fonctionnalités horizontalement. Difficile de refactorer verticalement (changer le modèle de données).
Performance~ MoyenChaque couche est un niveau d’indirection. Le mapping entre couches a un coût, mais négligeable dans la majorité des cas.
Scalabilité✗ LimitéArchitecture typiquement monolithique. On scale tout le système ou rien. Impossible de scaler une couche indépendamment.
Couplage DB → Métier✗ ProblèmeUncle Bob : le schéma DB risque de « dicter » la structure des entités métier. Le problème fondamental de l’architecture en couches.
Adapté pour✓ CRUD appsApplications de gestion, back-offices, APIs REST classiques. Le pattern idéal quand la logique métier est simple.
08

Quand l’utiliser — et quand passer à autre chose

Bon choix si…
Utilisez Layered quand
CRUDPetite équipeMVP rapideBack-office
Attention si…
Évitez Layered quand
DDD complexeMicroservicesHaute testabilité
Bonne pratique : Même dans une architecture Layered, appliquez le Dependency Inversion Principle (DIP). Faites dépendre la couche métier d’interfaces (et non d’implémentations concrètes). Vous obtiendrez les bénéfices de la testabilité de la Clean Architecture sans la complexité structurelle complète.
// LAYERED ARCHITECTURE — N-TIERRéférence : Clean Architecture — Robert C. Martin (2017)