Angular: Circular Dependencies vermeiden Teil 1/3

Als JavaScript-Framework ist Angular ein mächtiges Werkzeug zur schnellen Erstellung komplexer Web-Apps mit umfangreichem Funktionsumfang. Die Aufteilung der Software-Bestandteile in Module erleichtert die Entwicklung und Wartung des Codes und ermöglicht die Umsetzung vieler Code Quality Prinzipien.

Doch so angenehm die Modularisierung des Codes im Entwicklungsprozess ist, so schafft sie auch einige Tücken, die man als Entwickler*in von Anfang an im Auge behalten sollte.
Eine dieser Tücken, die uns im Laufe des Programmieralltags in der Vergangenheit gerne begegnete, ist das Thema Circular Dependencies. Achtet man nicht von Anfang an gezielt darauf, diese zu vermeiden, kommt es fast unweigerlich irgendwann zum unangenehmen Auftreten dieses Schreckgespensts und bereitet uns Entwicklern stundenlanges Kopfzerbrechen: Die App wird nicht mehr vernünftig kompiliert und wir stehen vor der Wahl –  umfangreiches Refactoring oder kurzes Zurechtpfuschen der Abhängigkeiten, sodass die App zumindest zeitweise (bis zur nächsten Circular Dependency) wieder funktioniert.

Hier wollen wir euch erklären, was sich hinter den Circular Dependencies verbirgt, wie ihr sie am besten vermeidet und was ihr tun solltet, falls doch mal der Circular Dependency Notfall eintritt.

Was sind eigentlich Circular Dependencies in Angular und wie entstehen sie?

Circular Dependencies sind kein Angular- oder TypeScript-spezifisches Problem. Generell sind zirkulare Abhängigkeiten in allen objektorientierten Sprachen zu vermeiden, da sie immer das Potential bergen, für Endlosschleifen und damit einen Absturz der Software zu sorgen.

Wie der Name schon sagt, ordnen sich dabei die Abhängigkeiten im Kreis an – das bedeutet, dass beispielsweise ein Service eine Function besitzt, die die Function eines anderen Services aufruft. Ruft diese Function wiederum eine Function des ersten Services auf, dreht sich das Ganze im Kreis: Wir haben eine Circular Dependency.

Das Beispiel nochmal konkreter:

Wir haben die Klasse FooService im Modul Foo, welche eine Function foo() besitzt. Diese ruft z.B. für eine Berechnung die Function bar() der Klasse BarService im Modul Bar auf:


export Class FooService {
...
   foo(): any {
      return bar();
   }
...
}

Ruft die bar()-Function nun wiederum die foo()-Function oder eine anderen Function innerhalb der FooService-Klasse auf, entsteht eine Circular Dependency: Das Foo-Modul ist abhängig vom Bar-Modul und das Bar-Modul ist abhängig vom Foo-Modul und so weiter.

Als Graph der Module sieht das Ganze dann so aus:

Abhängigkeiten zwischen den Modulen FooModule und BarModule

Das Beispiel ist natürlich sehr offensichtlich gewählt – eine Circular Dependency entsteht oft eher versteckt und unvorhergesehen.

Wie man daher am besten vorgehen sollte, um diese zu vermeiden, erklären wir euch im nächsten Teil.

Schreibe einen Kommentar

Coding Kombüse Logo

Kontakt

Wendenstraße 130
20537 Hamburg, Germany
moin [at] coding-kombuese.de

Vernetze dich mit uns

Bleibe auf dem Laufenden

Wir informieren dich über die digitale Welt und sagen dir welche Trends du im Auge behalten solltest.

Cookie Hinweis von Real Cookie Banner