image de chargement
Retour au glossaire

Anti-Corruption Layer (Couche Anti-Corruption)

Pattern architectural isolant le domaine métier des systèmes externes pour préserver l'intégrité du modèle et faciliter l'intégration legacy.

Mis à jour le 9 janvier 2026

L'Anti-Corruption Layer (ACL) est un pattern stratégique du Domain-Driven Design qui crée une couche d'isolation entre votre modèle de domaine et les systèmes externes ou legacy. Cette couche agit comme un traducteur bidirectionnel, protégeant votre architecture propre des contraintes et des modèles inadaptés imposés par des dépendances externes. Elle garantit que les concepts métier restent purs et alignés avec l'ubiquitous language de votre contexte.

Fondements

  • Isolation contextuelle : sépare rigoureusement les bounded contexts pour éviter la contamination de modèles incompatibles
  • Translation layer : transforme les structures de données externes en objets métier cohérents avec votre domaine
  • Abstraction des dépendances : encapsule les appels vers systèmes tiers derrière des interfaces métier expressives
  • Protection du modèle : préserve l'intégrité conceptuelle du core domain face aux contraintes techniques externes

Avantages

  • Autonomie architecturale : permet l'évolution indépendante du domaine métier sans être contraint par les systèmes legacy
  • Testabilité accrue : facilite les tests unitaires en isolant les dépendances externes derrière des facades mockables
  • Réduction de la dette technique : contient la complexité des intégrations dans une couche dédiée et remplaçable
  • Migration progressive : autorise le remplacement graduel de systèmes legacy sans refonte complète
  • Clarté du code métier : maintient un domaine core expressif, libre de compromis techniques liés aux intégrations

Exemple concret

Imaginons une application e-commerce moderne intégrant un ERP legacy qui retourne des données dans un format inadapté. L'ACL transforme ces structures techniques en objets métier cohérents :

anti-corruption-layer.ts
// Modèle métier pur (notre domaine)
interface Order {
  id: OrderId;
  customer: Customer;
  items: OrderItem[];
  totalAmount: Money;
  status: OrderStatus;
}

// Structure legacy de l'ERP (polluante)
interface LegacyOrderDTO {
  ORD_ID: string;
  CUST_CODE: string;
  LINE_ITEMS: string; // JSON stringifié
  AMT_TOTAL: number;
  STATUS_CD: number;
}

// Anti-Corruption Layer
class LegacyOrderAdapter {
  constructor(
    private legacyClient: LegacyERPClient,
    private customerRepository: CustomerRepository
  ) {}

  async findOrderById(orderId: OrderId): Promise<Order> {
    // Appel au système legacy
    const legacyData = await this.legacyClient.getOrder(orderId.value);
    
    // Traduction vers notre modèle métier
    return this.translateToOrder(legacyData);
  }

  private async translateToOrder(dto: LegacyOrderDTO): Promise<Order> {
    const customer = await this.customerRepository.findByCode(dto.CUST_CODE);
    const items = this.parseLineItems(dto.LINE_ITEMS);
    
    return new Order({
      id: new OrderId(dto.ORD_ID),
      customer,
      items,
      totalAmount: new Money(dto.AMT_TOTAL, 'EUR'),
      status: this.mapStatus(dto.STATUS_CD)
    });
  }

  private mapStatus(code: number): OrderStatus {
    const statusMap: Record<number, OrderStatus> = {
      1: OrderStatus.PENDING,
      2: OrderStatus.CONFIRMED,
      3: OrderStatus.SHIPPED,
      9: OrderStatus.CANCELLED
    };
    return statusMap[code] ?? OrderStatus.UNKNOWN;
  }

  private parseLineItems(jsonString: string): OrderItem[] {
    const rawItems = JSON.parse(jsonString);
    return rawItems.map(item => new OrderItem({
      productId: new ProductId(item.prod_id),
      quantity: item.qty,
      unitPrice: new Money(item.price, 'EUR')
    }));
  }
}

// Utilisation dans le service métier
class OrderService {
  constructor(private orderAdapter: LegacyOrderAdapter) {}

  async processOrder(orderId: OrderId): Promise<void> {
    // Le domaine ne connaît que son propre modèle
    const order = await this.orderAdapter.findOrderById(orderId);
    
    if (order.canBeShipped()) {
      order.markAsShipped();
      // Logique métier pure, sans pollution legacy
    }
  }
}

Mise en œuvre

  1. Identifier les bounded contexts : cartographier clairement les frontières entre votre domaine et les systèmes externes
  2. Définir les interfaces métier : créer des abstractions exprimant les besoins du domaine, pas les contraintes techniques
  3. Implémenter les adaptateurs : développer les traducteurs bidirectionnels entre modèles internes et externes
  4. Isoler les dépendances : encapsuler tous les appels externes derrière l'ACL pour éviter les fuites d'abstraction
  5. Tester exhaustivement : valider les transformations de données et gérer les cas limites des systèmes legacy
  6. Documenter les mappings : maintenir une documentation claire des correspondances entre modèles pour faciliter la maintenance

Conseil d'architecture

Ne créez pas d'ACL par défaut pour toute intégration. Ce pattern a un coût (complexité, maintenance). Réservez-le aux cas où le modèle externe menace réellement l'intégrité de votre domaine core. Pour des intégrations simples ou des services annexes, une interface directe peut suffire. L'ACL est un investissement stratégique pour protéger votre cœur métier.

Outils associés

  • AutoMapper / Mapster : bibliothèques .NET pour automatiser les transformations objet-à-objet complexes
  • Apache Camel : framework d'intégration permettant d'implémenter des ACL via des routes de transformation
  • GraphQL : peut servir d'ACL en exposant une API unifiée masquant l'hétérogénéité des sources backend
  • Strangler Fig Pattern : stratégie complémentaire pour remplacer progressivement les systèmes legacy protégés par un ACL

L'Anti-Corruption Layer représente un investissement stratégique dans la qualité architecturale long terme. En protégeant votre domaine métier des contraintes techniques externes, il réduit drastiquement la dette technique et facilite l'évolution continue de vos systèmes. Pour les organisations gérant du legacy ou multipliant les intégrations tierces, ce pattern devient un pilier de soutenabilité architecturale, permettant des refactorisations majeures sans risquer la cohérence du modèle métier.

L'argentestdéjàsurlatable.

En 1 heure, découvrez exactement combien vous perdez et comment le récupérer.