Ich habe diesen großartigen Vortrag von Simon Brown über modulare Monolithen von GOTO 2018 gesehen / gehört.
Darin erwähnt er einen Begriff namens Cargo Cult Programming und er hat mich wirklich beeindruckt.
Ich bin vor kurzem einem neuen Unternehmen mit einer neuen Programmiersprache, neuen Tools, neuen Prozessen und einem neuen Team beigetreten. Eigentlich ist es so ziemlich alles ’neu‘.
Dies hat mich veranlasst, in den letzten Monaten viel zu lernen. Da ich relativ erfahren bin, schaue ich lieber auf das Warum als auf das Wie, wenn ich neue Dinge lerne. Was ich festgestellt habe, ist, dass dies nicht der häufigste Ansatz ist.
Wenn ein Benutzer die Aufgabe hat, eine vorhandene Codebasis zu erweitern und die aktuelle Lösung zu erweitern, wird er höchstwahrscheinlich überprüfen, wie dies zuvor geschehen ist, und den Ansatz für seine Lösung kopieren. Sie können / werden blind diesem Muster folgen, so wie es vorher gemacht wurde. Zusätzliche Blöcke werden oben auf dem Turm hinzugefügt, ohne zu hinterfragen, ob es das Richtige ist. Wenn jeder dies tut, wird dies schließlich passieren.
Hier kommt der Begriff ‚Cargo Cult Programmierung‘ her.
Wikipedia erklärt es so:
Cargo Cult Programmierung ist ein Stil der Computerprogrammierung, der durch die rituelle Einbeziehung von Code oder Programmstrukturen gekennzeichnet ist, die keinen wirklichen Zweck erfüllen. Cargo Cult Programmierung ist typischerweise symptomatisch für einen Programmierer, der weder einen Fehler, den er zu lösen versuchte, noch die scheinbare Lösung versteht (vergleiche Shotgun Debugging, Deep Magic). Der Begriff Cargo Cult-Programmierer kann angewendet werden, wenn ein ungelernter oder unerfahrener Computerprogrammierer (oder ein Unerfahrener mit dem vorliegenden Problem) einen Programmcode von einem Ort zum anderen kopiert, ohne zu verstehen, wie er funktioniert oder ob er in seiner neuen Position erforderlich ist.
Cargo Cult-Programmierung kann sich auch auf die Praxis beziehen, ein Designmuster oder einen Codierungsstil blind anzuwenden, ohne die Gründe für dieses Designprinzip zu verstehen. Beispiele sind das Hinzufügen unnötiger Kommentare zu selbsterklärendem Code, das übereifrige Einhalten der Konventionen eines bestimmten Programmierparadigmas oder das Hinzufügen von Löschcode für Objekte, die die Garbage Collection automatisch gesammelt hätte.
Stellen Sie sich ein Szenario vor, in dem Sie an einem Fehler arbeiten und den Code finden, der den Fehler verursacht. Du bist dir nicht ganz sicher, was passiert, also bist du;
- Google den Fehler.
- Sie finden eine StackOverflow-Frage.
- Suche nach der Antwort mit den meisten Upticks.
- Kopieren Sie die Lösung und fügen Sie sie in Ihren Code ein.
- Versuchen Sie zu debuggen, um festzustellen, ob das Problem dadurch behoben wurde.
Es hat, also checken Sie es ein und fahren Sie fort.
Klingt bekannt?
Warum machen wir das? Warum nehmen wir dieses Snippet blind und verwenden es in unserer Implementierung unverändert?
Der Anwendungsfall ist wahrscheinlich nicht derselbe, daher wäre ich überrascht, wenn die Lösungen so wären. Abgesehen von einfachen Beispielen ist es wichtiger, die Gründe für die Lösung zu verstehen als die Lösung selbst. Es gibt viele Dinge, die man mit etwas, was man nicht versteht, nicht machen kann. Sie können es nicht ändern, verbessern oder testen. Sie können es nicht dokumentieren und Sie können es nicht besitzen.
Wir alle lieben das Neue, und besonders das Management scheint es zu mögen, populären Trends zu folgen und mit dem technologischen Fortschritt Schritt zu halten.
Die meisten Teams werden jetzt einen agilen Ansatz verfolgen. TDD und automatisierte Tests können in bestimmten Szenarien sehr nützlich sein, die kontinuierliche Integration entlastet das Infrastrukturteam erheblich, Big Data und KI können die Benutzerzufriedenheit und die Containerisierung erheblich verbessern, und in jüngster Zeit verlagern Microservices unsere alte Monolith-Architektur in kleinere eigenständige Dienste.
Jeder dieser Fortschritte ist für sich genommen brillant, und ich dulde keinen von ihnen. Meine Frage ist, ob wir sie alle in alle unsere Prozesse und Codes übernehmen müssen? Wir sehen Blog-Posts von Netflix, Facebook, Twitter, die zeigen, wie ihre Verwendung ihre Arbeitsweise verändert hat. Wenn große Unternehmen sie für notwendig halten, sollten wir das nicht auch? Hier erhebt die Cargo Cult-Programmierung wieder ihren hässlichen Kopf.
Wir müssen die Probleme mit unseren aktuellen Designs verstehen, warum sie aufgetreten sind und wie sie in Zukunft weggeworfen werden können. Ja, diese neuen Prozesse können uns bei unseren Problemen helfen, aber ihnen blind zu folgen in der schwachen Hoffnung, dass sie es tun, ist weder der Weg nach vorne, noch macht es irgendeinen logischen Sinn.
Ich erwähne Microservices speziell, da viele Unternehmen den Übergang zu machen scheinen, unter Berufung auf solche Vorteile wie:
- Schnellere Entwicklungszeit
- Hohe Skalierbarkeit
- Einfach zu verbessern
- Einfache Bereitstellung
- Autonome Teams mit der Freiheit, Technologie zu wählen
Was gibt es bei einer solchen Liste zu beachten? Lasst uns alle auf den Zug aufspringen!
Warten Sie eine Sekunde … gibt es Nachteile bei diesem Ansatz?
- Architektonische Komplexität
In monolithischen Architekturen befinden sich die Komplexität und die Anzahl der Abhängigkeiten innerhalb der Codebasis, während sich in Microservices-Architekturen die Komplexität auf die Interaktionen der einzelnen Dienste verlagert, die eine bestimmte Domäne implementieren
- Betriebliche Komplexität
- Skalierbare und kosteneffiziente Bereitstellung von Ressourcen
- Wie man Dutzende oder Hunderte von Microservice-Komponenten effektiv betreibt, ohne den Aufwand zu vervielfachen
- Wie man mit einem Mangel an Standards und heterogenen umgebungen, die unterschiedliche Technologien und Personen mit unterschiedlichen Fähigkeiten umfassen
- Umgang mit Versionierung
- Nachverfolgen und Debuggen von Interaktionen im gesamten System
- Verfolgen von Hunderten von Pipelines von Code-Bereitstellungen und deren Abhängigkeiten
Diese werden aus dem Whitepaper „Challenge of Microservices“ von Amazon entnommen. Jetzt weiß ich nichts über dich, aber die Nachteile sehen für mich viel beängstigender aus als die Vorteile. Noch einmal, ich sage nicht, dass dies nicht der richtige Ansatz ist, um unterzugehen, aber wenn diese Vorteile die Nachteile nicht überwiegen, was gewinnen Sie aus diesem Ansatz?
Das ‚öffentliche‘ Problem.
Es ist wirklich einfach, Hör auf, das Public Schlüsselwort zu verwenden, hör auf, automatisch öffentliche Klassen zu erstellen. Warum machen wir das?
Das Problem bei der Verwendung des public Schlüsselworts besteht darin, dass Sie die Vorteile der Kapselung verpassen. Warum verwenden wir es so oft? Es ist so ziemlich das Standardwort, das wir beim Erstellen von Klassen verwenden, alle Beispiele verwenden öffentliche Klassen, Assistenten und Snippets implementieren öffentliche Klassen. Es ist Zeit aufzuhören. Wie viele Personen haben einen öffentlichen Facebook-Account? Die meisten Dinge auf dieser Welt sind privat, so wie es unsere Klassen sein sollten. Machen Sie sie standardmäßig privat, und wenn Sie sie dann öffentlich machen müssen, ändern Sie sie dann.
Mit großer Erfahrung kommt große Besorgnis.
Je länger Sie in einem Feld sind, desto weniger naiv sind Sie gegenüber wahrgenommenen Verbesserungen, die ein neues Werkzeug oder ein neuer Prozess mit sich bringt. Die meisten der heutigen Ideen stammen aus jahrzehntelanger Forschung auf diesem Gebiet, die endlich angenommen werden. Sobald etwas Massenakzeptanz erlangt hat, ist es einfacher, sich wohl zu fühlen, wenn man es vollständig umarmt. Das heißt, wenn es das Richtige ist.
“ Gutes Urteilsvermögen kommt aus Erfahrung, und Erfahrung kommt aus schlechtem Urteilsvermögen“
– Rita Mae Brown
Also zögern Sie nicht, die Interwebs nach Lösungen und Tutorials für Ihre Probleme zu durchsuchen. Seien Sie sich nur bewusst, warum sie funktionieren, anstatt einfach wie. Wir alle lernen aus unseren eigenen Erfahrungen und Fehlern, daher wird das Verständnis der Grundlagen Sie davon abhalten, in Zukunft denselben Weg einzuschlagen.