Антикорупційний шар (anti-corruption layer, ACL) - прошарок між вашою моделлю й чужою моделлю (зовнішній API, легасі-система, інший контекст), що перекладає між ними й не дає чужим поняттям «проникнути» у ваш домен.
Проблема без нього. Платіжний провайдер повертає {"txn_state": "SETTLED_PARTIAL", "amt_minor": 12550, "cur": 980}. Якщо ці назви й коди розходяться по коду застосунку, ваш домен починає «говорити мовою провайдера»:
- перевірки
if ($payment->txn_state === 'SETTLED_PARTIAL')у десятках місць; - зміна API провайдера чи перехід на іншого ламає весь застосунок;
- модель провайдера (і її дивацтва) стає вашою моделлю.
З антикорупційним шаром:
final class LiqPayGateway implements PaymentGateway // інтерфейс вашого домену
{
public function status(PaymentId $id): PaymentStatus
{
$raw = $this->client->get("/transactions/{$id}");
return match ($raw['txn_state']) {
'SETTLED' => PaymentStatus::Paid,
'SETTLED_PARTIAL' => PaymentStatus::PartiallyPaid,
'REVERSED', 'CHARGEBACK' => PaymentStatus::Refunded,
default => PaymentStatus::Pending,
};
}
}
Домен знає лише PaymentGateway і PaymentStatus. Усі перетворення - в одному класі.
Що робить шар:
- переклад понять (статуси, назви полів, коди валют);
- перетворення форматів (одиниці, дати, ідентифікатори);
- захист від дивацтв чужої системи (нестабільні поля, помилки, обмеження);
- фасад - простий інтерфейс над складним чи незручним API.
Коли потрібен:
- інтеграція з легасі-системою, модель якої не хочеться переносити в нову;
- зовнішні API, що можуть змінитися чи бути замінені (платежі, доставка, CRM);
- поступова міграція з моноліту: новий модуль спілкується зі старим кодом через ACL (патерн Strangler Fig);
- взаємодія обмежених контекстів з різними моделями.
Ціна: додатковий код і ще один шар, який треба підтримувати. Для простої, стабільної інтеграції (одне поле з API) повноцінний ACL - зайвий; досить невеликого класу-адаптера.
Зв'язок з патернами: технічно ACL часто складається з адаптерів, фасадів і перетворювачів - але суть не в патернах, а в захисті моделі домену від чужих понять.
Докладніше в документації: Azure: патерн Anti-corruption Layer