Eliminierung technischer Schulden mit PHPStan, Rector PHP und PHPUnit. Über 20 Jahre Praxiserfahrung in skalierbaren Backends.
- Aktualisiert:
- Autor:
- Roland Golla
Anti Corruption Layer: Definition
Ein Anti Corruption Layer ist eine Übersetzungsschicht zwischen zwei Systemen mit unterschiedlicher Sprache. Sie nimmt Anfragen und Daten des einen Systems entgegen und übersetzt sie in das Modell des anderen, sodass beide Seiten ihre eigenen Begriffe und Technologien behalten können.
Eric Evans beschrieb das Muster 2003 in Domain Driven Design. Der Name ist Programm: Ohne diese Schicht sickern die Eigenheiten des Altsystems in den neuen Code. Aus einer sauberen Bestellung wird wieder ein Datensatz mit kryptischen Spaltennamen, Statuscodes als Zahlen und Feldern, die je nach Kontext etwas anderes bedeuten. Nach einem Jahr sieht der neue Code aus wie der alte, nur in moderner Syntax. In der Praxis besteht ein Anti Corruption Layer aus Adaptern, Fassaden und Übersetzern, die genau an der Grenze zwischen beiden Welten sitzen.
Inhalt
Anti Corruption Layer mit NCA: Schnelle Hilfe vom Experten
Saubere Grenzen im Code sind unser tägliches Geschäft. Never Code Alone entwickelt seit über 20 Jahren mit Symfony und PHP, unser CMS läuft auf Sulu. Wo Grenzen halten müssen, prüfen wir sie mit Werkzeugen statt mit Absichtserklärungen: Architekturregeln in der Pipeline, statische Analyse auf jedem Merge Request, Tests an den Übergabepunkten.
Wir unterstützen Teams im PHP Consulting und beim Refactoring gewachsener Codebasen. Für die Grenzkontrolle setzen wir Deptrac und den PHP Architecture Tester ein, für Typsicherheit PHPStan und Psalm. Getestet wird mit PHPUnit, die Persistenz läuft über Doctrine Migrations.
Lass uns sprechen
Finde das passende Angebot für dein Projekt
Anfrage-Konfiguration
Starten Sie Ihre Anfrage
Gesetzliche Konformität & Inklusion. Optimierung von Performance und Conversion durch radikal nutzerzentriertes, universelles Design.
Skalierbare KI-Systeme mit echtem Code Ownership. CI/CD, Backup-Strategien und Infrastruktur, die mit deinem Team wächst.
Anfrage-Konfiguration
Worauf liegt dein Fokus?
Wähle die Expertise, die dein Projekt jetzt am dringendsten benötigt.
Was passiert ohne Übersetzungsschicht
Ein Team startet mit einem frischen Modul. Die Klassen heißen wie die Begriffe im Unternehmen, die Typen sind eng, alles wirkt aufgeräumt. Dann kommt die erste Anbindung ans Altsystem. Ein Feld heißt dort anders, ein Status ist eine Zahl, ein Datum kommt als String in einem eigenwilligen Format.
Der schnelle Weg ist, das durchzureichen. Ein Getter hier, ein Sonderfall da. Nach einem halben Jahr trägt das neue Modell die alten Feldnamen, die alten Statuscodes und die alten Annahmen. Die Modernisierung hat den Code umgezogen, aber nicht verbessert.
Der Anti Corruption Layer zieht eine Linie. Auf der einen Seite spricht das System die Sprache des Altsystems, auf der anderen die Sprache der Fachabteilung. Dazwischen sitzt Code, dessen einzige Aufgabe die Übersetzung ist. Dieser Code darf hässlich sein, denn er ist der Ort, an dem die Hässlichkeit endet.
Umsetzung in PHP: Interface plus Adapter
In PHP ist der Einstieg unspektakulär. Das neue Modul definiert ein Interface in seiner eigenen Sprache. Wie die Daten wirklich beschafft werden, interessiert es nicht.
interface InvoiceRepository
{
public function findByNumber(string $number): Invoice;
public function save(Invoice $invoice): void;
}
Dahinter stehen zwei Implementierungen. Die eine spricht mit der neuen Datenbank über Doctrine, die andere ruft das Altsystem über HTTP und baut aus der Antwort ein sauberes Objekt. Das Umwandeln passiert genau dort und nirgendwo sonst.
Gut zu sehen ist der Kontrast: Draußen die alten Feldnamen aus dem Bestandssystem, drinnen das saubere Modell.
final class LegacyInvoiceRepository implements InvoiceRepository
{
public function findByNumber(string $number): Invoice
{
$raw = $this->client->fetch('/rechnung/' . $number);
// Translation happens here and nowhere else
return new Invoice(
number: $raw['rechnr'],
status: Status::fromLegacyCode($raw['st']),
);
}
}
Das Muster hat zwei Richtungen. Der eingehende Übersetzer schützt das neue Modell vor den Formen des Altsystems. Der ausgehende Adapter sorgt dafür, dass fremde Protokolle nicht in die Domäne wandern, wenn das neue Modul etwas zurückschreibt. In der Regel braucht man beides.
Während einer Migration kommt oft eine dritte Variante dazu: eine Implementierung, die beide Seiten gleichzeitig bedient. Sie schreibt in das alte und das neue System, damit die Daten während des Übergangs nicht auseinanderlaufen. Beim Lesen fragt sie zuerst die neue Quelle und fällt auf die alte zurück, wenn dort noch nichts liegt.
Wann sich der Aufwand lohnt und wann nicht
Ein Anti Corruption Layer ist kein Selbstzweck. Er kostet eine zusätzliche Schicht, die betrieben, überwacht und mitgepflegt werden will, und er kann Latenz hinzufügen. Diese Kosten müssen sich rechnen.
Anti Corruption Layer: Einsatz abwägen
| Situation | Empfehlung | Begründung |
|---|---|---|
| Alt und neu nutzen verschiedene Begriffe | Einsetzen | Ohne Übersetzung wandert die alte Sprache ins neue Modell |
| Migration läuft über Monate parallel | Einsetzen | Die Schicht hält beide Seiten unabhängig voneinander änderbar |
| Fremdsystem ohne eigene Kontrolle | Einsetzen | Änderungen von außen treffen nur den Adapter, nicht die Domäne |
| Einfaches CRUD mit identischen Feldern | Verzichten | Es gibt nichts zu übersetzen, die Schicht wäre reiner Overhead |
Grenzen prüfen statt hoffen
Eine Grenze, die nur in der Dokumentation steht, hält keine drei Sprints. Irgendwann liegt ein Termindruck an, jemand importiert die Legacy Klasse direkt in einen Service, und die Schicht hat ihren Zweck verloren.
Deshalb gehört die Regel in die Pipeline. Deptrac oder der PHP Architecture Tester definieren Schichten und verbieten Zugriffe, die nicht erlaubt sind. Verstößt ein Merge Request dagegen, schlägt der Build fehl. Das ist die einzige Form von Architekturregel, die dauerhaft wirkt.
Zusätzlich lohnt es sich, den Übersetzer selbst zu testen. Ein Unit Test für jede Umwandlung dokumentiert, welche Altcodes es gibt und was aus ihnen wird. Genau diese Tests sind später die beste Beschreibung des Altsystems, die ein Team besitzt. Über die Oberfläche prüft ein Cypress Test, ob der Gesamtablauf trotz Übersetzung stimmt. Mehr dazu im Bereich Cypress Testing.
an isolating layer to provide clients with functionality in terms of their own domain model
Die NCA Erfahrung mit sauberen Grenzen
In jedem Modernisierungsprojekt taucht dieselbe Frage auf: Wie viel Altsystem darf ins neue Modul? Unsere Antwort ist immer gleich, nämlich so wenig wie möglich, und geprüft durch Werkzeuge.
Die Grenzen selbst überwachen Deptrac, PHP Architecture Tester und PHP Arkitect. Ungenutzte Reste nach dem Umbau finden Class Leak und Unused Public. Für die Typsicherheit an den Übergabepunkten sorgen PHPStan, Type Coverage und Type Perfect. Die Übersetzer selbst testen wir mit PHPUnit, das Zusammenspiel prüfen Symfony KernelTestCase und HttpClient MockResponse für externe Aufrufe.
Erreichen Sie unsere PHP Consultant Spezialisten
Wir sind Experten für PHP und helfen Ihnen, Ihre digitalen Herausforderungen zu meistern. Unser erfahrenes Team unterstützt Sie bei PHP Updates, PHP Refactoring und berät Sie remote zu allen Fragen rund um PHP. Mit unseren vollautomatischen CI/CD Deployments und einer robusten Docker-Infrastruktur bringen wir Ihre PHP-Projekte auf das nächste Level. Vertrauen Sie auf unsere Expertise für zuverlässige und skalierbare PHP-Lösungen.
Häufige Fragen zum Anti Corruption Layer
Was Teams uns fragen, wenn sie zum ersten Mal eine Übersetzungsschicht bauen.
Was ist ein Anti Corruption Layer 2026 einfach erklärt?
Eine Übersetzungsschicht zwischen zwei Systemen, die unterschiedliche Sprachen sprechen. Sie nimmt Daten und Anfragen der einen Seite entgegen und wandelt sie in das Modell der anderen um. So bleibt das neue Domänenmodell frei von den Eigenheiten des Altsystems, ohne dass am Altsystem etwas geändert werden muss.
Ist ein Anti Corruption Layer 2026 dasselbe wie ein Adapter?
Nein, die Ebenen sind verschieden. Der Adapter ist ein technisches Entwurfsmuster, der Anti Corruption Layer eine Architekturentscheidung. In der Umsetzung besteht die Schicht meist aus mehreren Adaptern, Fassaden und Übersetzern. Der Adapter ist also ein Baustein der Schicht, nicht ihr Ersatz.
Wie viel Aufwand kostet die Schicht 2026 wirklich?
Sie kostet zusätzlichen Code, der getestet und gepflegt werden muss, und kann Latenz hinzufügen. Bei einer echten Modellabweichung ist dieser Aufwand kleiner als die Alternative, nämlich ein neues System, das nach zwölf Monaten wieder aussieht wie das alte. Bei identischen Datenstrukturen lohnt sich die Schicht dagegen nicht.
Wo gehört die Schicht 2026 im Symfony Projekt hin?
Meist als eigener Namespace neben der Domäne, etwa Infrastructure oder Adapter. Die Domäne definiert Interfaces, die Infrastrukturschicht implementiert sie. Der Service Container verdrahtet beides. Wichtig ist, dass die Domäne nie in die Gegenrichtung greift, das lässt sich mit Deptrac in der Pipeline erzwingen.
Brauche ich 2026 einen eigenen Service dafür?
In den meisten Fällen nicht. Die Schicht kann als Namespace innerhalb der Anwendung leben, das ist der einfachere und schnellere Weg. Ein separater Dienst lohnt sich, wenn mehrere Anwendungen dieselbe Übersetzung brauchen oder die Anbindung eigene Skalierung erfordert.
Was ist der Unterschied zwischen Inbound und Outbound?
Inbound schützt das eigene Modell vor Daten, die von außen hereinkommen. Outbound sorgt dafür, dass beim Schreiben nach außen keine fremden Protokolle in die Domäne wandern. In der Praxis braucht man beide Richtungen, also Übersetzer für eingehende Anfragen und Adapter für ausgehende Aufrufe.
Wie verhindere ich, dass die Grenze wieder aufweicht?
Nur durch Automatisierung. Architekturregeln in Deptrac oder im PHP Architecture Tester definieren, welche Schicht welche verwenden darf. Ein Verstoß bricht den Build. Regeln, die nur in einem Wiki stehen, halten erfahrungsgemäß wenige Wochen, bis der erste Termindruck kommt.
Wie hängt der Anti Corruption Layer mit Strangler Fig zusammen?
Sie ergänzen sich. Strangler Fig regelt über ein Gateway, welche Anfrage auf welchem System landet. Der Anti Corruption Layer regelt, wie beide Systeme miteinander reden, während die Migration läuft. Ohne die Übersetzungsschicht schleppt jede migrierte Route die alten Begriffe mit.
Kann ich die Schicht später wieder entfernen?
Ja, und genau das ist das Ziel. Wenn das Altsystem abgeschaltet ist, wird der übersetzende Adapter überflüssig. Die Interfaces bleiben, nur die Implementierung dahinter fällt weg. Wer die Übersetzer sauber getrennt hält, hat diesen Rückbau später an einer Stelle statt verstreut über die ganze Anwendung.
Wie teste ich eine Übersetzungsschicht sinnvoll?
Mit Unit Tests pro Umwandlung. Jeder Altcode, jedes Sonderformat und jeder Grenzfall bekommt einen Testfall. Diese Tests sind später oft die beste vorhandene Dokumentation des Altsystems. Ergänzend prüfen Integrationstests, ob die Anbindung als Ganzes funktioniert, und E2E Tests den fachlichen Ablauf.
Hilft KI beim Bauen solcher Adapter?
Ja, besonders beim Erschließen unbekannter Datenstrukturen. Modelle sind gut darin, aus Beispielantworten Muster zu erkennen und Testfälle vorzuschlagen. Die Entscheidung, wie das neue Modell aussehen soll, bleibt beim Team. Ein Adapter, der einfach die alten Feldnamen übernimmt, verfehlt seinen Zweck komplett.
Wie unterstützt Never Code Alone bei diesem Thema?
Wir sehen uns den Bestand an, schneiden gemeinsam die Grenzen und richten die Regeln in der Pipeline ein, damit sie halten. Am Anfang steht ein kostenloses Kennenlernen, danach schätzen wir den Aufwand. Abgerechnet wird transparent nach Minuten, ohne Paket und ohne Mindestlaufzeit.