Codeabhängigkeiten sind der Teufel.

“ Veränderung ist die einzige Konstante …“ – Heraklit (Philosoph)

Die Tools, Bibliotheken und Frameworks, mit denen wir heute unsere Webanwendungen erstellen, unterscheiden sich drastisch von denen, die wir noch vor wenigen Jahren verwendet haben.

In wenigen Jahren werden sich die meisten dieser Technologien wieder dramatisch verändert haben. Dennoch machen viele von uns diese zu einem zentralen, untrennbaren Bestandteil unserer Apps.

Wir importieren, verwenden und erben von den Frameworks des Monats, als ob sie alle für immer unverändert wären. Nun … sind sie nicht. Und das ist ein Problem.

Nach mehr als 20 Jahren Entwicklung, Design und Architektur von Webanwendungen habe ich zwei wichtige Wahrheiten erkannt:

  1. Externe Abhängigkeiten stellen eine große Bedrohung für die langfristige Stabilität und Lebensfähigkeit jeder Anwendung dar.
  2. Es wird immer schwieriger – wenn nicht sogar unmöglich – jede Art von nicht-trivialer App zu erstellen, ohne externe Abhängigkeiten zu nutzen.

In diesem Artikel geht es darum, diese beiden Wahrheiten in Einklang zu bringen, damit unsere Apps die größten Überlebenschancen haben.

Das Kaninchenloch ist in der Tat sehr tief.

Wenn wir anfangen, an all die Dinge zu denken, von denen unsere Web-Apps abhängen, ist es einfach, an ein Dutzend oder mehr zu denken, bevor wir überhaupt zum Code kommen:

  • Stromversorgung
  • Konnektivität
  • Firewall
  • DNS
  • Serverhardware (CPU, Festplatte, RAM, …)
  • Kühlung
  • Virtualisierungsplattform
  • Containerplattform
  • Betriebssystem
  • Webserver-Plattform
  • App-Server-Plattform
  • Webbrowser

Als Entwickler ist es gut, sich dieser Dinge bewusst zu sein, aber wir können oft nicht viel dagegen tun. Ignorieren wir sie also vorerst und sprechen wir nur über den Code.

Im Code gibt es drei Arten von Abhängigkeiten:

1. Abhängigkeiten, die wir kontrollieren

Dies ist Code, der von uns oder unserer Organisation geschrieben wurde und ihm gehört.

2. Abhängigkeiten, die wir nicht kontrollieren

Dies ist Code, der von einem Drittanbieter oder einer Open-Source-Software-Community geschrieben wurde.

3. Abhängigkeiten nach dem Entfernen

Dies sind die Codeabhängigkeiten, von denen unsere Codeabhängigkeiten von Drittanbietern abhängen. (Sag das dreimal schnell!)

Wir werden hauptsächlich über Abhängigkeiten sprechen, die wir nicht kontrollieren.

Abhängigkeiten, die wir kontrollieren, und Abhängigkeiten, die einmal entfernt wurden, können immer noch Kopfschmerzen verursachen, aber im Falle von Abhängigkeiten, die wir kontrollieren, sollten wir in der Lage sein, direkt einzugreifen und Probleme zu mildern.

Im Falle von Abhängigkeiten, die einmal entfernt wurden, können wir uns normalerweise darauf verlassen, dass sich ein Dritter darum kümmert, da er auch von diesen abhängig ist.

Warum Codeabhängigkeiten von Drittanbietern gut sind

Ein großer Teil Ihrer Webanwendung ist vorhanden, um häufig auftretende Probleme zu lösen: authentifizierung, Autorisierung, Datenzugriff, Fehlerbehandlung, Navigation, Protokollierung, Verschlüsselung, Anzeige einer Liste von Elementen, Validierung von Formulareingaben usw…

Unabhängig davon, welchen Technologie-Stack Sie verwenden, besteht eine gute Chance, dass gemeinsame Lösungen für diese Probleme existieren und als Bibliotheken verfügbar sind, die Sie einfach erwerben und in Ihre Codebasis einbinden können. Das Schreiben dieser Sachen komplett von Grund auf neu ist in der Regel eine Verschwendung von Zeit.

Sie möchten sich auf Code konzentrieren, der entweder ein ungewöhnliches Problem oder ein häufiges Problem auf ungewöhnliche Weise löst. Das macht Ihre Anwendung wertvoll: Der Code, der die Geschäftsregeln implementiert, die nur für Ihre App gelten — die „geheime Sauce“.“

Googles Such— und Seitenranking-Algorithmus, Facebooks Timeline-Filterung, Netflix ‚ Abschnitt „Empfohlen für Sie“ und Datenkomprimierungsalgorithmen – der Code hinter all diesen Funktionen ist „secret Sauce.“

Code von Drittanbietern – in Form von Bibliotheken — ermöglicht es Ihnen, diese standardisierten Funktionen Ihrer App schnell zu implementieren, sodass Sie sich auf Ihre „geheime Sauce“ konzentrieren können.“

Warum Codeabhängigkeiten von Drittanbietern schlecht sind

Schauen Sie sich eine nicht triviale Web-App an, die in den letzten Jahren erstellt wurde, und Sie werden absolut erstaunt sein, wie viel Code tatsächlich aus einer Bibliothek eines Drittanbieters stammt. Was ist, wenn sich eine oder mehrere dieser Bibliotheken von Drittanbietern drastisch ändern oder verschwinden oder kaputt gehen?

Wenn es Open Source ist, können Sie es vielleicht selbst beheben. Aber wie gut verstehen Sie den gesamten Code in dieser Bibliothek, die Sie nicht besitzen? Ein wichtiger Grund, warum Sie eine Bibliothek überhaupt verwenden, besteht darin, die Vorteile des Codes zu nutzen, ohne sich um alle Details kümmern zu müssen. Aber jetzt steckst du fest. Sie haben Ihr Vermögen vollständig an diese Abhängigkeiten gebunden, die Sie nicht besitzen und nicht kontrollieren.

Keine Sorge, am Ende dieses Artikels finden Sie eine neue Hoffnung.

Vielleicht denken Sie, ich übertreibe oder spreche aus rein akademischer Sicht. Lassen Sie mich Ihnen versichern — ich habe Dutzende von Beispielen von Kunden, die sich selbst völlig ausspioniert haben, indem sie Code von Drittanbietern zu eng in ihre App eingebettet haben. Hier ist nur ein aktuelles Beispiel …

Ein ehemaliger Kunde von mir hat seine App mit einem Backend-as-a-Service-Anbieter namens Parse von Facebook erstellt. Sie verwendeten eine von Parse bereitgestellte JavaScript-Client-Bibliothek, um den Parse-Dienst zu nutzen. Dabei haben sie ihren gesamten Code — einschließlich des „Secret Sauce“ —Codes – eng an diese Bibliothek gekoppelt.

Drei Monate nach der ersten Produkteinführung meines Kunden — gerade als sie anfingen, mit echten, zahlenden Kunden eine gute Traktion zu bekommen – kündigte Parse an, dass es heruntergefahren werde.

Anstatt sich nun darauf zu konzentrieren, ihr Produkt zu iterieren und ihren Kundenstamm zu vergrößern, musste mein Kunde herausfinden, wie er entweder auf eine selbst gehostete Open-Source-Version von Parse migrieren oder Parse vollständig ersetzen konnte.

Die Störung, die dies für eine junge, junge Anwendung verursachte, war so groß, dass mein Kunde die App schließlich vollständig verschrottete.

Gleichgewicht zwischen Gut und Böse

Vor einigen Jahren bestand meine erste Lösung zur Überwindung der Risiken unter Beibehaltung der Vorteile von Bibliotheken von Drittanbietern darin, sie mit dem Adaptermuster zu umschließen.

Im Wesentlichen wickeln Sie den Code eines Drittanbieters in eine Adapterklasse oder ein Modul ein, die / das Sie geschrieben haben. Dies funktioniert dann, um die Funktionen der Bibliotheken von Drittanbietern in einer von Ihnen kontrollierten Weise verfügbar zu machen.

Wenn Sie dieses Muster verwenden, müssen Sie nur ein wenig Adaptercode reparieren, wenn sich eine Bibliothek oder ein Framework eines Drittanbieters ändert oder verschwindet. Der Rest Ihrer App bleibt intakt.

Adaptermusterdiagramm von Dofactory.com

Das klingt auf dem Papier gut. Wenn Sie in sich geschlossene Abhängigkeiten haben, die nur wenige Funktionen bereitstellen, reicht dies aus. Aber die Dinge können schnell hässlich werden.

Können Sie sich vorstellen, die gesamte React-Bibliothek (einschließlich JSX) umschließen zu müssen, bevor Sie etwas davon verwenden? Wie wäre es mit jQuery, Angular oder dem Spring Framework in Java? Das wird schnell zum Albtraum.

Heutzutage empfehle ich einen differenzierteren Ansatz …

Bewerten Sie für jede Abhängigkeit, die Sie Ihrer Codebasis hinzufügen möchten, das Risiko, das sie einführt, indem Sie zwei Faktoren multiplizieren:

  1. Die Wahrscheinlichkeit, dass sich die Abhängigkeit materiell ändert.
  2. Der Schaden, den eine wesentliche Änderung der Abhängigkeit Ihrer Anwendung zufügen würde.

Es ist weniger wahrscheinlich, dass sich eine Bibliothek oder ein Framework eines Drittanbieters ändert, wenn einige oder alle der folgenden Dinge zutreffen:

  • Es gibt es schon seit mehreren Jahren und hatte mehrere Major Releases.
  • Es ist weit verbreitet durch viele kommerziellen anwendungen.
  • Es hat die aktive Unterstützung einer großen Organisation – vorzugsweise einer bekannten Firma oder Institution.

Eine Bibliothek oder ein Framework eines Drittanbieters fügt Ihrer Anwendung weniger Schaden zu, wenn einige oder alle der folgenden Dinge zutreffen:

  • Es wird nur von einem kleinen Teil Ihrer Anwendung verwendet, anstatt durchgehend verwendet zu werden.
  • Der Code, der davon abhängt, ist nicht Teil dieser „geheimen Sauce“, über die ich zuvor gesprochen habe.
  • Das Entfernen erfordert nur minimale Änderungen an Ihrer Codebasis.
  • Ihre gesamte Anwendung ist sehr klein und kann schnell neu geschrieben werden. (Seien Sie vorsichtig mit diesem – es ist selten sehr lange wahr.)

Je riskanter etwas ist, desto wahrscheinlicher sollten Sie es einwickeln oder ganz vermeiden.

Wenn es um den Code geht, der für das Wertversprechen Ihrer Anwendung wirklich von zentraler Bedeutung ist — Ihre „geheime Sauce“ —, müssen Sie ihn äußerst schützen. Machen Sie diesen Code so unabhängig wie möglich. Wenn Sie unbedingt eine Abhängigkeit verwenden müssen, sollten Sie sie injizieren, anstatt direkt darauf zu verweisen. Selbst dann sei vorsichtig.

Manchmal bedeutet dies, „Nein“ zu einer Bibliothek eines Drittanbieters zu sagen, die Sie für wirklich cool halten oder die Sie aus dem einen oder anderen Grund wirklich verwenden möchten. Sei stark. Vertrau mir, es wird sich auszahlen. Fragen Sie einfach all die Leute, die viel in die allererste Version von Angular investiert haben, oder meinen ehemaligen Kunden, der Parse überall verwendet hat. Es macht keinen Spaß. Glaub mir.

Apropos Spaß, schauen Sie sich das an…

Abhängigkeitsdiagramm für TinyTag explorer

Das obige Bild zeigt das Abhängigkeitsdiagramm für eine Anwendung namens TinyTag Explorer.

Das Erstellen eines Abhängigkeitsdiagramms für Ihre vorhandenen Apps ist eine großartige Möglichkeit, das Risiko zu verstehen, das durch Ihre Abhängigkeiten entsteht. Ich habe eine Liste kostenloser Tools zum Generieren von Diagrammen zusammengestellt, die den oben genannten in einer Vielzahl von Sprachen ähnlich sind, darunter JavaScript, C #, Java, PHP und Python. Sie können es hier bekommen.

Hilf mir, anderen zu helfen

Ich möchte so vielen Entwicklern wie möglich helfen, indem ich mein Wissen und meine Erfahrung mit ihnen teile. Bitte helfen Sie mir, indem Sie unten auf die Schaltfläche ❤ Empfehlen (grünes Herz) klicken.

Vergessen Sie nicht, Ihre Liste der kostenlosen Abhängigkeitsgraphengeneratoren hier abzurufen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.