Hier ist ein
Zitat von Linus Torvalds für 2006 :
Ich glaube fest an die Entwicklung von Code rund um Daten und nicht umgekehrt, und ich denke, dies ist einer der Gründe, warum git ziemlich erfolgreich war ... Tatsächlich argumentiere ich, dass der Unterschied zwischen einem schlechten und einem guten Programmierer darin besteht, ob er mehr denkt wichtig Ihr Code oder Ihre Datenstrukturen. Schlechte Programmierer sorgen sich um Code. Gute Programmierer sorgen sich um Datenstrukturen und ihre Beziehungen.
Was
Eric Raymonds „Einreichungsregel“ von 2003 sehr ähnlich ist:
Verwandeln Sie Wissen in Daten, damit die Programmlogik dumm und zuverlässig wird.
Hier ist nur eine Zusammenfassung von Ideen wie
Rob Pikes Gedanken von 1989 :
Daten dominieren. Wenn Sie die richtigen Datenstrukturen auswählen und alles gut organisieren, sind die Algorithmen fast immer selbstverständlich. Datenstrukturen, keine Algorithmen, spielen eine zentrale Rolle bei der Programmierung.
Er zitiert
Fred Brooks aus dem Jahr 1975 :
Präsentation ist die Essenz der Programmierung
Hinter der Meisterschaft steht der Einfallsreichtum, der macht
wirtschaftliche und schnelle Programme. Dies ist fast immer das Ergebnis.
strategischer Durchbruch, keine taktische Fähigkeit. Manchmal so strategisch
Ein Durchbruch ist ein Algorithmus wie eine schnelle Fourier-Transformation.
vorgeschlagen von Cooley und Tukey oder Ersetzen von n²-Vergleichen durch n log n beim Sortieren.
In den meisten Fällen ergibt sich aus der Präsentation ein strategischer Durchbruch
Daten oder Tabellen. Der Kern des Programms ist hier. Zeigen Sie mir die Flussdiagramme, ohne die Tabellen zu zeigen, und ich werde in die Irre gehen. Zeig mir deine
Tabellen und Flussdiagramme werden höchstwahrscheinlich nicht benötigt: Sie sind offensichtlich.
Seit fast einem halben Jahrhundert sagen kluge Köpfe immer wieder: Konzentrieren Sie sich zuerst auf die Daten. Aber manchmal scheint es, dass dies der klügste Rat ist, den jeder vergisst.
Ich werde einige echte Beispiele geben.
Hoch skalierbares System, das fehlgeschlagen ist
Dieses System wurde ursprünglich mit der Erwartung einer unglaublichen Skalierbarkeit bei hoher CPU-Belastung entwickelt. Nichts synchrones. Überall Rückrufe, Warteschlangen und Arbeitspools.
Es gab jedoch zwei Probleme. Das erste war, dass die "Prozessorlast" nicht so hoch war - eine Aufgabe dauerte maximal einige Millisekunden. Der größte Teil der Architektur hat also mehr geschadet als geholfen. Das zweite Problem war, dass das "hoch skalierbare verteilte System" tatsächlich nur auf einer Maschine funktionierte. Warum? Weil die gesamte Kommunikation zwischen asynchronen Komponenten mithilfe von Dateien im lokalen Dateisystem durchgeführt wurde, was nun zu einem Engpass für jede Skalierung geworden ist. Das ursprüngliche Design war überhaupt nicht an Daten gebunden, mit Ausnahme des Schutzes lokaler Dateien im Namen der "Einfachheit". Der Hauptteil des Projekts war all dieser zusätzlichen Architektur gewidmet, die „offensichtlich“ notwendig war, um mit der „hohen Belastung“ der CPU fertig zu werden.
Serviceorientierte Architektur, die immer noch datenorientiert ist
Dieses System folgte dem Design von Microservices aus Einzweckanwendungen mit REST-APIs. Eine der Komponenten war eine Datenbank, in der Dokumente gespeichert sind (hauptsächlich Antworten auf Standardformulare und andere elektronische Dokumente). Natürlich hat sie die API zum Speichern und Abrufen von Daten festgelegt, aber ziemlich schnell waren komplexere Suchfunktionen erforderlich. Die Entwickler waren der Ansicht, dass das Hinzufügen dieser Funktion zu einem vorhandenen API-Dokument den Prinzipien des Microservice-Designs widerspricht. Da sich 'search' wesentlich von 'get / put' unterscheidet, sollte die Architektur diese nicht kombinieren. Darüber hinaus planten sie, ein Drittanbieter-Tool für die Arbeit mit dem Index zu verwenden. Aus diesem Grund war auch die Erstellung einer neuen Service-Suche sinnvoll.
Als Ergebnis wurden eine Such-API und ein Suchindex erstellt, die im Wesentlichen zu einem Duplikat der Daten in der Hauptdatenbank wurden. Diese Daten wurden dynamisch aktualisiert. Daher sollte jede Komponente, die die Dokumentdaten über die Hauptdatenbank-API geändert hat, auch eine Anforderung zum Aktualisieren des Index über die Such-API senden. Bei Verwendung der REST-API ist dies nicht ohne Race-Bedingung möglich, sodass die beiden Datensätze von Zeit zu Zeit nicht mehr synchron waren.
Trotz der versprochenen Architektur waren die beiden APIs durch ihre Datenabhängigkeiten eng miteinander verbunden. Später erkannten die Entwickler, dass der Suchindex mit einem gemeinsamen Dokumentendienst kombiniert werden sollte, was das System wesentlich wartbarer machte. Doing One funktioniert auf Datenebene, jedoch nicht auf Verbebene.
Fantastisch modularer und konfigurierbarer Schlammklumpen
Dieses System war eine Art automatisierte Bereitstellungspipeline. Das ursprüngliche Entwicklungsteam wollte ein Tool flexibel genug gestalten, um Bereitstellungsprobleme im gesamten Unternehmen zu lösen. Sie haben eine Reihe von Plug-in-Komponenten mit einem Konfigurationsdateisystem geschrieben, das nicht nur die Komponenten konfiguriert, sondern auch als
domänenspezifische Sprache (DSL) für die Programmierung der Anpassung der Komponenten an die Pipeline fungiert.
Schneller Vorlauf auf einige Jahre, und das Tool wurde zum "Programm". Es gab eine lange Liste bekannter Fehler, die noch niemand behoben hatte. Niemand wollte den Code berühren, aus Angst, etwas zu zerbrechen. Niemand hat die Flexibilität von DSL genutzt. Alle Benutzer haben die gleiche garantierte Arbeitskonfiguration wie alle anderen kopiert und eingefügt.
Was ist schief gelaufen? Obwohl im ursprünglichen Projektdokument häufig Wörter wie "modular", "getrennt", "erweiterbar" und "benutzerdefiniert" verwendet wurden, sagte er überhaupt nichts über die Daten. Daher wurden Datenabhängigkeiten zwischen Komponenten auf unregulierte Weise unter Verwendung eines global gemeinsamen JSON-Blobs verarbeitet. Im Laufe der Zeit machten die Komponenten immer mehr undokumentierte Annahmen darüber, was im JSON-Blob enthalten ist oder nicht. Natürlich erlaubte DSL, dass Komponenten in beliebiger Reihenfolge neu angeordnet wurden, aber die meisten Konfigurationen funktionierten nicht.
Der Unterricht
Ich habe diese drei Projekte ausgewählt, weil es einfach ist, die allgemeine These anhand ihres Beispiels zu erklären, ohne die anderen zu berühren. Einmal habe ich versucht, eine Website zu erstellen, und stattdessen über eine Art servile XML-Datenbank gehängt, die meine Datenprobleme nicht einmal gelöst hat. Es gab ein anderes Projekt, das sich in einen gebrochenen Anschein der Hälfte der Funktionalität von
make
verwandelte, wieder, weil ich nicht dachte, was ich wirklich brauchte. Ich habe bereits über die Zeit geschrieben, die für die Erstellung einer
endlosen Hierarchie von OOP-Klassen aufgewendet
wurde, die in den Daten hätte codiert werden sollen .
Update:
Anscheinend denken viele immer noch, dass ich mich über jemanden lustig machen will. Meine echten Kollegen wissen, dass ich viel mehr daran interessiert bin, echte Probleme zu beheben und nicht diejenigen zu beschuldigen, die diese Probleme verursacht haben, aber okay, das denke ich über die Entwickler, die an diesen Projekten beteiligt sind.
Ehrlich gesagt trat die erste Situation eindeutig auf, weil der Systemarchitekt mehr daran interessiert war, wissenschaftliche Arbeit anzuwenden als ein echtes Problem zu lösen. Viele von uns können dafür verantwortlich gemacht werden (ich auch), aber es ärgert unsere Kollegen wirklich. Schließlich müssen sie bei der Unterstützung helfen, wenn wir ein Spielzeug satt haben. Wenn Sie sich selbst erkennen, seien Sie nicht beleidigt, hören Sie einfach auf (obwohl ich lieber mit einem verteilten System auf einem Knoten als mit einem System in meiner „XML-Datenbank“ arbeiten würde).
Im zweiten Beispiel gibt es nichts Persönliches. Manchmal scheint es, dass jeder sagt, wie wunderbar es ist, Dienste zu teilen, aber niemand spricht darüber, wann es besser ist, dies nicht zu tun. Die Menschen lernen ständig aus ihren eigenen bitteren Erfahrungen.
Die dritte Geschichte ist tatsächlich einigen der klügsten Leute passiert, mit denen ich je gearbeitet habe.
(Ende des Updates).
Die Frage "Was wird über die durch die Daten verursachten Probleme gesagt?" Es stellt sich als nützlicher Lackmustest für ein gutes Systemdesign heraus. Es ist auch sehr praktisch, um falsche „Experten“ mit ihren Ratschlägen zu identifizieren. Probleme mit der Architektur komplexer, komplizierter Systeme sind Datenprobleme, daher ignorieren falsche Experten sie gerne. Sie zeigen Ihnen eine überraschend schöne Architektur, sagen aber nichts darüber aus, für welche Daten sie geeignet sind und (was wichtig ist) für welche Daten sie nicht geeignet sind.
Ein falscher Experte könnte beispielsweise sagen, dass Sie das Pub / Sub-System verwenden sollten, da Pub / Sub-Systeme lose gekoppelt sind und lose gekoppelte Komponenten wartbarer sind. Es klingt schön und gibt schöne Diagramme, aber es ist das Gegenteil von Denken. Pub / Sub macht Ihre Komponenten nicht lose miteinander verbunden. Pub / Sub
selbst ist lose gekoppelt, was Ihren Datenanforderungen entsprechen kann oder nicht.
Andererseits ist eine gut gestaltete datenorientierte Architektur von großer Bedeutung. Funktionale Programmierung, Service-Mesh, RPC, Entwurfsmuster, Ereignisschleifen, was auch immer, jeder hat seine eigenen Vorzüge. Aber ich persönlich habe gesehen, dass viel erfolgreichere Produktionssysteme an
langweiligen alten DBMS arbeiten .