Model protection
The new domain remains shaped by current business language rather than legacy artifacts.
During migration or external integration, teams often let legacy terminology and awkward data structures leak directly into the new model. The Anti-Corruption Layer pattern introduces an explicit translation boundary so the new domain can stay coherent even while it still depends on older systems.
A legacy order system may encode payment status, fulfillment status, and manual review state in one overloaded field. If the new ordering model copies that structure directly, the old confusion spreads into the new service. An Anti-Corruption Layer absorbs the mismatch and preserves model clarity.
An Anti-Corruption Layer sits between two models and translates concepts, messages, and data structures. It protects the new side from inappropriate assumptions and naming. The pattern is especially important when integrating with large legacy systems or external vendors whose model quality or semantics differ from your own.
The goal is not to insult the old system. It is to preserve the integrity of the new model so future design remains comprehensible. A good ACL makes the translation explicit and testable instead of scattering legacy compromises everywhere.
The new domain remains shaped by current business language rather than legacy artifacts.
Mappings and conversions live in one intentional boundary instead of leaking into services everywhere.
ACLs are especially useful during staged replacement and long-lived coexistence.
Map overloaded legacy vocabulary into cleaner domain concepts.
Transform awkward external payloads into stable internal commands and views.
Translate old combined states into more precise internal lifecycle stages.
When the external system changes, the ACL absorbs most of the impact.
package org.javaomnibus.integration.legacy;
public final class LegacyOrderTranslator {
public OrderSnapshot translate(LegacyOrderRecord legacy) {
return new OrderSnapshot(
legacy.legacyOrderNumber(),
mapOrderStatus(legacy.combinedStatus()),
mapPaymentStatus(legacy.combinedStatus()),
legacy.customerNumber()
);
}
private OrderStatus mapOrderStatus(String combinedStatus) {
return combinedStatus.startsWith("SHIP") ? OrderStatus.FULFILLING : OrderStatus.PENDING_PAYMENT;
}
}