ProgramGuru

Anti-Corruption Layer Pattern

Anti-Corruption Layer: start from the problem

See the responsibilities

Legacy systemUses its own vocabulary
Translation boundaryMaps meaning and rejects unsupported cases
New modelKeeps explicit domain rules
New serviceActs on validated translated data
Legacy system: Uses its own vocabulary → Translation boundary: Maps meaning and rejects unsupported cases → New model: Keeps explicit domain rules → New service: Acts on validated translated data

A new order service has a clean money and status model, while a legacy system uses obscure field names and different status values. Importing that representation everywhere can distort the new service’s rules.

This is a service boundaries pattern lesson. Follow the responsibilities, inspect the small JavaScript example and compare the design choices. The example is local teaching code; its boundary is explained before you apply the idea to a real service.

What you’ll learn

  • Explain the problem Anti-Corruption Layer addresses and the roles involved.
  • Follow the example and distinguish this pattern from nearby alternatives.
  • Choose when the benefit justifies the extra responsibilities and testing.

How the responsibilities work

An Anti-Corruption Layer translates between systems so one domain model does not become shaped by the other’s conventions. It can include adapters, mapping and explicit compatibility policies. Translation must preserve meaning or return a useful incompatibility result.

Our example maps one legacy order into the new model and rejects an unsupported currency. It translates a bounded format, not every possible legacy rule. Reconciliation and changes in either contract need ongoing ownership.

Follow a small example

Read the JavaScript from top to bottom and compare the expected output. The values are chosen to make this pattern’s responsibility visible. This example runs in one local execution context; it does not create remote services, durable storage or production access controls.

JavaScript · local teaching example

function translate(old) {
  if (!['Y', 'N'].includes(old.FLAG)) throw new Error('Unsupported status');
  if (old.CUR !== 'USD') throw new Error('Unsupported currency');
  return {id: old.ORDER_NO, status: old.FLAG === 'Y' ? 'ready' : 'pending', cents: old.CENTS};
}
console.log(JSON.stringify(translate({ORDER_NO: 'O1', FLAG: 'Y', CUR: 'USD', CENTS: 1250})));

Expected output

{"id":"O1","status":"ready","cents":1250}

Choose a design and inspect the consequence

Compare the design choices

Legacy introduces a new status code.
The two systems already share the required model.

Compare the visible consequences. With JavaScript enabled, choose an option in each scenario to assemble your decision record.

This is an exploratory design exercise. It does not run infrastructure, measure capacity or replace the lesson’s quiz.

Use the consequences to explain your decision, including the simpler alternative.

Apply the pattern to two situations. Select one option in each situation to build a decision record. Every option and its consequence stays visible, and you can change your choices.

When it helps—and what it costs

Use it when integration risks contaminating one system’s business model with another’s assumptions, especially during gradual migration.

A translation layer adds delay, tests and maintenance. Unknown codes, rounding and partial data need explicit rules. Do not silently map every unrecognized status into success. Decide whether translation failure should reject, quarantine or seek review.

Distinguish the neighbouring patterns

Adapter reconciles a component interface. Anti-Corruption Layer addresses a wider domain boundary. Strangler Fig migrates responsibility gradually and can use this translation boundary.

Follow interface-level adaptation, migration in controlled slices, explicit service contracts to compare the specific responsibility before combining patterns.

For further reading, use Microsoft’s Anti-Corruption Layer guidance. Compare it with this original example and the guarantee required by your application.

Check your pattern reasoning

Why reject an unsupported currency in the example?
Choose one answer. You can try again.

Answer and explanation

The new model’s money meaning must remain explicit.

A silent relabel can produce a wrong amount.

Check your pattern reasoning

What is this layer protecting?
Choose one answer. You can try again.

Answer and explanation

The new system’s domain model and rules.

The boundary translates foreign conventions deliberately.

Name the responsibility before choosing the pattern

For Anti-Corruption Layer, describe the problem, the participating roles and the observable contract. Use the example as a starting point and test the boundaries identified in the trade-offs. A pattern name alone does not establish correctness or performance.

Return to the design-pattern guide to compare families, or apply the idea alongside explicit service contracts.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Asynchronous Request/Reply Pattern →