Was ich aus meiner bitteren Erfahrung gelernt habe (über 30 Jahre in der Softwareentwicklung)

Bild

Dies ist eine zynische, klinische Sammlung dessen, was ich über 30 Jahre in der Softwareentwicklung gelernt habe. Ich wiederhole, einige Dinge sind sehr zynisch, und der Rest ist das Ergebnis langer Beobachtungen an verschiedenen Arbeitsorten.

Softwareentwicklung


Zuerst die technischen Daten, dann der Code


Wenn Sie nicht genau wissen, was Sie lösen möchten, wissen Sie nicht, welchen Code Sie schreiben sollen.
Beschreiben Sie zunächst, wie Ihre Anwendung funktioniert, bevor Sie mit der Programmierung beginnen.

„Ohne Anforderungen oder ein Projekt ist Programmieren die Kunst, einer leeren Textdatei Fehler hinzuzufügen.“ - Louis Sraigley

Manchmal reicht sogar eine „kurze Präsentation“ aus - nicht mehr als zwei Absätze, die beschreiben, was Ihre Anwendung tut.

Es gab Zeiten, in denen ich aufgrund ungeschriebener Schritte mehr Zeit damit verbracht habe, den Code zu betrachten und mich zu fragen, was ich als nächstes tun soll. Dies ist ein gutes Zeichen dafür, dass es Zeit ist, anzuhalten und die Situation mit Kollegen zu besprechen. Oder vielleicht die Entscheidung überdenken.

Beschreiben Sie die Schritte als Kommentare


Wenn Sie nicht wissen, wie Sie beginnen sollen, beschreiben Sie den Datenfluss auf oberster Ebene in Ihrer Anwendung einfach in Ihrer Muttersprache. Und füllen Sie dann den ungültigen Code zwischen den Kommentaren aus.

Oder noch besser: Lesen Sie jeden Kommentar als Funktion und schreiben Sie dann eine Funktion, die genau das tut.

Gurke hilft Ihnen, Erwartungen zu verwirklichen


Gurke ist ein Testbeschreibungsformat, dessen Prinzip lautet: "Wenn sich das System in einem bestimmten Zustand befindet und etwas passiert, wird dies erwartet." Wenn Sie keine Testtools verwenden, die Gherkin verstehen, erhalten Sie eine gute Vorstellung davon, was Sie von der Anwendung erwarten können.

Unit-Tests sind gut, Integrationstests sind noch besser


In meinem aktuellen Job testen wir nur Module und Klassen. Zum Beispiel schreiben wir Tests nur für die Präsentationsebene, dann schreiben wir Tests nur für die Controller-Ebene und so weiter. Dies hilft uns zu verstehen, ob alles in Ordnung ist, ermöglicht es uns jedoch nicht, das gesamte Bild des Geschehens zu sehen. Dazu sind Integrationstests, die das Verhalten des gesamten Systems überprüfen, viel nützlicher.

Tests Verbessern Sie APIs


Wir programmieren im Rahmen von Ebenen: Es gibt eine Speicherebene, die unsere Daten ewig machen soll; Es gibt eine Verarbeitungsebene, die die gespeicherten Daten irgendwie transformieren muss. Es gibt eine Präsentationsschicht, die Informationen zur Präsentation von Daten usw. enthält.

Wie gesagt, Integrationstests sind besser, aber wenn Sie die Ebenen selbst testen, können Sie besser verstehen, wie ihre APIs aussehen. Dann werden Sie die Situation mit den Aufrufen von etwas besser verstehen: Ist die API zu kompliziert? Muss ich so viele Daten in der Nähe haben, um einen Anruf zu tätigen?

Führen Sie Tests durch, die Sie über die Befehlszeile ausführen können


Ich meine, nicht die Befehlszeilen selbst sind für ein Objekt wichtig, sondern Ihr Wissen über die Befehle zum Ausführen der Tests, Ihre Fähigkeit, deren Ausführung zu automatisieren, die Sie dann im Tool für die kontinuierliche Integration anwenden können.

Seien Sie bereit, Ihren Code in den Warenkorb zu senden


Viele derjenigen, die auf der Grundlage von Tests (TDD) mit der Entwicklung beginnen, sind verärgert, wenn Sie ihnen mitteilen, dass Sie möglicherweise einen Großteil ihres Codes neu schreiben müssen, einschließlich dessen, was Sie selbst geschrieben haben.

TDD wurde für das Werfen von Code erfunden : Je mehr Sie über ein Problem erfahren, desto besser verstehen Sie, dass das, was Sie geschrieben haben, es auf lange Sicht nicht lösen wird.

Mach dir darüber keine Sorgen. Ihr Code ist keine Wand: Wenn Sie ihn immer wegwerfen müssen, ist dies keine Verschwendung. Natürlich haben Sie Zeit beim Schreiben von Code verloren, aber jetzt verstehen Sie das Problem besser.

Eine gute Sprache hat Tests integriert


Ich versichere Ihnen: Wenn die Standard-Sprachbibliothek über ein Test-Framework verfügt - wenn auch nur minimal -, sind die Tests in dem damit verbundenen Ökosystem besser als in einer Sprache, die kein solches Framework hat, unabhängig von den Vorzügen externer Test-Frameworks für diese Sprache.

Über die Zukunft nachzudenken bedeutet, Energie zu verschwenden


Wenn Entwickler versuchen, ein Problem zu lösen, versuchen sie manchmal, einen Weg zu finden, der alle Probleme löst, einschließlich der Probleme, die in Zukunft auftreten können.

Ich sage Ihnen eines: Diese zukünftigen Probleme werden niemals auftreten, und Sie müssen einen riesigen Stapel Code begleiten, der nicht vollständig verwendet wird, oder Sie müssen alles neu schreiben, weil es so viel unbenutzten Code gibt.

Lösen Sie das Problem jetzt. Dann entscheiden Sie Folgendes. Dann der nächste. Sobald Sie ein Muster bemerken, das sich aus diesen Entscheidungen ergibt, finden Sie erst dann Ihre „universelle Lösung“.

Dokumentation ist eine zukünftige Liebesbotschaft für sich


Wir alle wissen, was für eine Blutung es ist, verdammte Dokumentation über Funktionen, Klassen und Module zu schreiben. Aber wenn Sie den Verlauf Ihrer Gedanken verstehen, als Sie diese oder jene Funktion geschrieben haben, kann dies Ihren Arsch in Zukunft retten.

Funktionsdokumentation ist sein Vertrag


Wenn Sie mit dem Schreiben der Dokumentation beginnen, erstellen Sie tatsächlich einen Vertrag (möglicherweise mit sich selbst): "Ich behaupte, dass diese Funktion dies tut, und genau das tut sie."

Wenn Sie später feststellen, dass Ihr Code nicht mit der Dokumentation übereinstimmt, handelt es sich um ein Codeproblem und nicht um eine Dokumentation.

Wenn die Beschreibung der Funktion "und" enthält, ist dies schlecht


Eine Funktion sollte nur eines tun. Wenn Sie eine Dokumentation dazu schreiben und feststellen, dass Sie ein „und“ hinzugefügt haben, bedeutet dies, dass die Funktion etwas anderes ausführt. Teilen Sie es in zwei Funktionen und entfernen Sie das „und“.

Verwenden Sie keine booleschen Werte als Parameter


Wenn Sie eine Funktion entwickeln, könnten Sie versucht sein, ein Flag hinzuzufügen. Tu das nicht.
Lassen Sie mich getUserMessages eines Beispiels erklären: getUserMessages , Sie haben ein Nachrichtensystem und es gibt eine Funktion getUserMessages , die alle Nachrichten an den Benutzer zurückgibt. Es gibt jedoch Situationen, in denen Sie entweder die kurze Essenz jeder Nachricht (z. B. den ersten Absatz) oder die gesamte Nachricht zurückgeben müssen. Daher fügen Sie einen Parameter in Form eines Flags oder eines Booleschen Werts hinzu, den Sie retrieveFullMessage aufrufen.

Wieder tun Sie dies nicht.

Weil diejenigen, die Ihren Code lesen, getUserMessage(userId, true) und sich fragen, worum es geht?

Oder Sie können die Funktion getUserMessagesFull umbenennen und getUserMessagesFull oder ähnliches eingeben, aber jede Funktion ruft einfach die ursprüngliche getUserMessage mit true oder false - aber die Schnittstelle außerhalb Ihrer Klasse / Ihres Moduls ist klar.
Fügen Sie jedoch keine Flags oder Booleschen Parameter zu Funktionen hinzu.

Achten Sie auf Änderungen an der Benutzeroberfläche


Im vorherigen Absatz habe ich die Umbenennung einer Funktion erwähnt. Wenn Sie die Quelle steuern, in der die Funktion verwendet wird, ist dies kein Problem, sondern nur eine Frage der Suche und des Austauschs. Wenn die Funktion jedoch von der Bibliothek bereitgestellt wird, müssen Sie den Namen nicht nach Belieben ändern. Dies wird viele andere Anwendungen beschädigen, die Sie nicht kontrollieren, und viele Menschen verärgern.

Sie können neue Funktionen erstellen und die aktuelle Funktion in einem Dokument oder mittels Code als unerwünscht markieren. Und nach ein paar Veröffentlichungen kannst du sie endlich töten.

Hässliche Lösung: Erstellen Sie neue Funktionen, markieren Sie die aktuelle als unerwünscht und fügen Sie am Anfang der Funktion sleep um zu erzwingen, dass diejenigen, die die alte Funktion verwenden, aktualisiert werden.

Gute Sprachen haben eine integrierte Dokumentation


Wenn die Sprache ihre eigene Art der Dokumentation von Funktionen, Klassen, Modulen und allem anderen verwendet und es sogar einen einfachen Dokumentationsgenerator gibt, ist alles, was erwähnt wird, gut dokumentiert (nicht großartig, aber zumindest gut).

Und Sprachen ohne integrierte Dokumentation sind oft schlecht dokumentiert.

Sprache ist mehr als nur Sprache


Sie schreiben in einer Programmiersprache und lassen die Dinge „funktionieren“. Aber es gibt bei weitem nicht nur spezielle Wörter: Die Sprache hat ein Assemblierungssystem, ein Abhängigkeitsmanagementsystem, Tools für die Interaktion von Tools, Bibliotheken und Frameworks, es gibt eine Community, es gibt eine Möglichkeit, mit Menschen zu interagieren.

Wählen Sie keine Sprachen aus, um die Verwendung zu vereinfachen. Denken Sie daran, dass Sie die Syntax einfach finden können. Wenn Sie diese Sprache auswählen, können Sie auch festlegen, wie die Ersteller der Sprache mit ihrer Community kommunizieren.

Manchmal ist es besser, die Anwendung abstürzen zu lassen, als nichts zu tun.


Obwohl dies seltsam klingt, ist es besser, keine Fehlerbehandlung hinzuzufügen, als sie leise abzufangen und nichts zu tun.

Java hat ein leider gemeinsames Muster:

 try { something_that_can_raise_exception() } catch (Exception ex) { System.out.println(ex); } 

Mit einer Ausnahme wird hier nichts unternommen, nur eine Meldung wird angezeigt.

Wenn Sie nicht wissen, wie Sie mit dem Fehler umgehen sollen, lassen Sie ihn auftreten, damit Sie zumindest herausfinden können, wann er aufgetreten ist.

Wenn Sie wissen, wie man verarbeitet, tun Sie es


Im Gegensatz zum vorherigen Absatz: Wenn Sie wissen, wann eine Ausnahme, ein Fehler oder ein Ergebnis auftritt und Sie wissen, wie Sie damit umgehen sollen, tun Sie dies. Zeigen Sie die Fehlermeldung an, versuchen Sie, die Daten irgendwo zu speichern, verwerfen Sie die vom Benutzer eingegebenen Daten zur späteren Verwendung im Protokoll - verarbeiten Sie sie einfach.

Typen sprechen darüber, welche Daten Sie haben


Der Speicher ist nur eine Folge von Bytes. Bytes sind einfach Zahlen von 0 bis 255. Was diese Zahlen bedeuten, wird im Sprachtypsystem beschrieben.

In C ist der Zeichentyp (Zeichentyp) mit einem Wert von 65 wahrscheinlich der Buchstabe "A", und ein int mit einem Wert von 65 ist die Zahl 65.

Beachten Sie dies, wenn Sie mit Ihren Daten arbeiten.

Beim Hinzufügen von Booleschen Werten vergessen viele, die Anzahl der True Werte zu überprüfen. Kürzlich bin ich auf dieses Beispiel-JavaScript gestoßen:

 console.log(true+true === 2); > true console.log(true === 1); > false 

Wenn Ihre Daten ein Schema haben, speichern Sie es als Struktur


Wenn die Daten einfach sind, z. B. nur zwei Felder, können Sie sie in einer Liste speichern (oder in einem Tupel, wenn Ihre Sprache dies zulässt). Wenn die Daten jedoch ein Schema haben - ein festes Format -, verwenden Sie immer eine Struktur oder Klasse, um sie zu speichern.

Erkennen Sie den Frachtkult und halten Sie sich von ihm fern


Die Idee des "Frachtkultes" ist, dass wir es können, wenn jemand es tut. Meistens ist der Frachtkult einfach eine „einfache Flucht“ vor dem Problem: Warum sollten wir darüber nachdenken, wie Benutzerdaten richtig gespeichert werden, wenn X dies bereits getan hat?

"Wenn die Big Company Daten auf diese Weise speichert, können wir das."

"Wenn Big Company es nutzt, ist das gut."

"Das richtige Werkzeug für die Aufgabe" ist eine Möglichkeit, Ihre Meinung durchzusetzen


Der Ausdruck „das richtige Werkzeug für die Aufgabe“ sollte bedeuten, dass es für etwas ein richtiges und ein falsches Werkzeug gibt. Verwenden Sie beispielsweise eine bestimmte Sprache oder ein bestimmtes Framework anstelle der aktuellen Sprache oder des aktuellen Frameworks.

Aber jedes Mal, wenn ich diesen Ausdruck von jemandem höre, drücken die Leute ihre Lieblingssprache / ihren Lieblingsrahmen auf diese Weise, anstatt beispielsweise die richtige Sprache / den richtigen Rahmen.

Das „richtige Werkzeug“ ist offensichtlicher als Sie denken


Vielleicht nehmen Sie jetzt an einem Projekt teil, in dem Sie Text verarbeiten möchten. Vielleicht möchten Sie sagen: "Verwenden wir Perl, weil jeder weiß, dass Perl sehr gut Text verarbeitet."

Was Sie vergessen: Ihr Team ist auf C spezialisiert. Jeder kennt C, nicht Perl.

Wenn dies ein kleines Projekt "auf dem Knie" ist, ist es natürlich auf Perl möglich. Und wenn das Projekt für das Unternehmen wichtig ist, ist es besser, es in C zu schreiben.

PS: Ihr heroisches Projekt (mehr dazu weiter unten) kann daran scheitern.

Passen Sie nicht in das, was außerhalb Ihres Projekts liegt


Anstatt geeignete Erweiterungstools zu verwenden, ändern Benutzer manchmal externe Bibliotheken und Frameworks. Nehmen Sie beispielsweise Änderungen direkt an WordPress oder Django vor.

So können Sie das Projekt einfach und sehr schnell für die Wartung ungeeignet machen. Sobald die neue Version veröffentlicht wird, müssen Sie die Änderungen mit dem Hauptprojekt synchronisieren. In Kürze werden Sie feststellen, dass das Anwenden der Änderungen nicht mehr möglich ist, und die alte Version des externen Tools voller Sicherheitslücken belassen.

Datenströme schlagen Muster


Das ist meine persönliche Meinung. Wenn Sie verstehen, wie Daten Ihren Code durchlaufen sollen, ist dies für ihn besser, als wenn Sie eine Reihe von Entwurfsmustern verwenden.

Entwurfsmuster werden verwendet, um Lösungen zu beschreiben, nicht um sie zu finden.


Wieder meine persönliche Meinung. Nach meinen Beobachtungen werden meistens Entwurfsmuster verwendet, um eine Lösung zu finden. Infolgedessen wird die Lösung - und manchmal das Problem selbst - verzerrt, um dem Muster zu entsprechen.

Lösen Sie zuerst Ihr Problem. Suchen Sie eine gute Lösung und suchen Sie dann in den Mustern, um zu erfahren, wie Ihre Lösung heißt.

Ich habe das schon oft gesehen: Wir haben ein Problem, das Muster ist nahe an der richtigen Lösung, verwenden wir das Muster, jetzt müssen wir der richtigen Lösung eine Menge von allem hinzufügen, damit es mit dem Muster übereinstimmt.

Lernen Sie die Grundlagen der funktionalen Programmierung


Sie müssen sich nicht eingehend mit den Fragen „Was sind Monaden?“ Oder „Ist es ein Funktor?“ Befassen. Aber denken Sie daran: Sie sollten Daten nicht ständig ändern. neue Elemente mit neuen Werten erstellen (Daten als unveränderlich betrachten); Führen Sie nach Möglichkeit Funktionen und Klassen aus, in denen keine internen Zustände gespeichert sind (reine Funktionen und Klassen).

Kognitive Anstrengung ist der Feind der Lesbarkeit.


" Kognitive Dissonanz " ist ein verschleierter Ausdruck. "Um dies zu verstehen, muss ich mich gleichzeitig an zwei (oder mehr) verschiedene Dinge erinnern." Und je indirekter diese Informationen sind, desto mehr Aufwand müssen Sie aufwenden, um sie im Kopf zu behalten.

Das Hinzufügen von Booleschen Werten zum Zählen von True Werten ist beispielsweise eine milde Version der kognitiven Dissonanz. Wenn Sie den Code lesen und die Funktion sum() , die bekanntlich alle Zahlen in der Liste hinzufügt, erwarten Sie eine Liste mit Zahlen. und ich traf Leute, die sum() um True Werte in einer Liste von Booleschen Werten zu zählen, was völlig verwirrend ist.

Magische Nummer sieben plus oder minus zwei


Die " magische Zahl " ist ein Artikel in der Psychologie, der die Anzahl der Elemente beschreibt, die eine Person gleichzeitig im Kurzzeitgedächtnis halten kann.

Wenn Sie eine Funktion haben, die eine Funktion aufruft, die eine Funktion aufruft, die eine Funktion aufruft, die eine Funktion aufruft, die eine Funktion aufruft, dann ist dies nur die Hölle für den Leser Ihres Codes.

Denken Sie nur darüber nach: Ich werde das Ergebnis dieser Funktion erhalten, es an die zweite Funktion übergeben, das Ergebnis erhalten, die dritte übergeben usw.

Darüber hinaus sprechen Psychologen heute häufiger über die magische Zahl VIER als über sieben.
Denken Sie in der Kategorie „Zusammensetzung der Funktionen“ (zum Beispiel „Ich werde diese Funktion aufrufen, dann das, dann dort ...“) und nicht in der Kategorie „Aufruf der Funktionen“ (zum Beispiel „Diese Funktion wird das aufrufen, sie wird das aufrufen“. .. ").

Die Schnitte sind gut, aber nur kurzfristig


Viele Sprachen, Bibliotheken und Frameworks bieten Verknüpfungsmethoden, um die Anzahl der von Ihnen eingegebenen Zeichen zu verringern.

Aber später kommt es zu Ihnen zurück, und Sie werden gezwungen sein, die Schnitte zu entfernen und alles in seiner Gesamtheit zu schreiben.
Finden Sie also zuerst heraus, was eine bestimmte Abkürzung tut, bevor Sie sie verwenden.
Sie müssen das Ganze zunächst nicht schreiben und dann in Abkürzung ändern: Tun Sie, was die Abkürzungen für Sie tun, und zumindest werden Sie verstehen, was möglicherweise schief geht oder wie Sie etwas durch eine ungekürzte Version ersetzen können.

Widerstehen Sie der Versuchung der "Leichtigkeit"


Natürlich hilft Ihnen die IDE bei der automatischen Fertigstellung einer Reihe von Dingen und erleichtert Ihnen das Erstellen eines Projekts. Aber verstehen Sie überhaupt, was dort passiert?

Wissen Sie, wie Ihr Build-System funktioniert? Wenn Sie es ohne IDE ausführen müssen, können Sie es tun?

Erinnern Sie sich an Funktionsnamen ohne automatische Vervollständigung? Ist es möglich, etwas zu beschädigen oder umzubenennen, damit es leichter zu verstehen ist?

Interessieren Sie sich für das, was unter der Haube passiert.

Verwenden Sie IMMER Zeitzonen in Datumsangaben


Fügen Sie beim Arbeiten mit Datumsangaben immer Zeitzonen hinzu. Sie werden immer Probleme mit der Nichtübereinstimmung von Zeitzonen auf Computern und Servern haben, und Sie verlieren viel Zeit für das Debuggen, wenn Sie versuchen zu verstehen, warum die Schnittstelle die falsche Zeit anzeigt.

Verwenden Sie IMMER UTF-8


Bei Codierungen treten dieselben Probleme auf wie bei Datumsangaben. Konvertieren Sie daher immer Zeichenfolgenwerte in UTF-8, speichern Sie sie in Datenbanken in UTF-8 und kehren Sie von Ihren APIs zu UTF-8 zurück.

Sie können in jede andere Codierung konvertieren, aber UTF-8 hat den Codierungskrieg besiegt, sodass Sie am einfachsten daran festhalten können.

Fangen Sie dumm an


Eine der Möglichkeiten, sich von der IDE zu entfernen, besteht darin, "auf dumme Weise zu starten": Nehmen Sie einfach den Compiler, einen beliebigen Editor mit Code-Hervorhebung und - programmieren, erstellen, ausführen.

Ja, das ist nicht einfach. Wenn Sie später eine Art IDE verwenden, werden Sie nur an die Schaltflächen "Ja, das wird gestartet" denken. Genau das tun IDEs.

Protokolle sind für Ereignisse, nicht für die Benutzeroberfläche.


Lange Zeit habe ich Protokolle verwendet, um Benutzern zu zeigen, was mit der Anwendung passiert. Weißt du, weil es viel einfacher ist, eins als zwei zu benutzen.

Verwenden Sie das Standardausgabeformular, um Benutzer über Ereignisse zu informieren. Für die Fehlerberichterstattung Standardfehlermeldungen. Verwenden Sie die Protokolle nur zum Speichern von Daten, die Sie später problemlos verarbeiten können.

Protokolle sind keine Benutzeroberfläche, sondern eine Entität, die Sie analysieren müssen, um Informationen zum richtigen Zeitpunkt abzurufen. Protokolle sollten nicht für Menschen lesbar sein.

Debugger überbewertet


Ich habe Beschwerden von vielen gehört, dass Code-Editoren ohne Debugger schrecklich sind, gerade weil sie keine Debugger haben.

Wenn Ihr Code jedoch in Betrieb ist, können Sie Ihren bevorzugten Debugger nicht ausführen. Zur Hölle, Sie können nicht einmal Ihre Lieblings-IDE ausführen. Aber Journaling ... es funktioniert überall. Möglicherweise verfügen Sie zum Zeitpunkt des Sturzes nicht über die gewünschten Informationen (z. B. aufgrund unterschiedlicher Protokollierungsstufen). Sie können jedoch die Protokollierung aktivieren, um den Grund später herauszufinden.

Ich schweige über die Tatsache, dass Debugger selbst schlecht sind, sie bieten einfach nicht die Hilfe, die viele von ihnen erwarten.

Verwenden Sie immer ein Versionsverwaltungssystem


„Dies ist nur meine blöde Anwendung, mit der ich etwas lernen möchte“ - dies rechtfertigt nicht das Fehlen eines Versionsverwaltungssystems.

Wenn Sie ein solches System von Anfang an verwenden, ist es einfacher, ein Rollback durchzuführen, wenn Sie einen Fehler machen.

Eine Änderung pro Commit


Ich habe Leute getroffen, die die folgenden Nachrichten in Commits schreiben: "Behebt Problem 1, 2 und 3". Sofern sich nicht alle diese Probleme gegenseitig duplizieren - von denen zwei bereits geschlossen sein sollten - sollten drei Commits anstelle von einem vorhanden sein.

Halten Sie sich an das Prinzip "eine Änderung pro Commit". Und mit Änderung meine ich eine Änderung in einer Datei. Wenn Sie drei Dateien ändern müssen, schreiben Sie diese Dateien zusammen. Fragen Sie sich: "Wenn ich diese Änderung zurücksetze, was sollte dann verschwinden?"

"Git add -p" hilft Ihnen bei vielen Änderungen


Dies gilt nur für Git. Sie können Dateien mit dem Parameter "-p" teilweise zusammenführen, sodass Sie nur Änderungen auswählen können, die sich aufeinander beziehen, während die anderen für das neue Commit übrig bleiben.

Strukturieren Sie Projekte nach Daten oder Typ, nicht nach Funktionalität


Die meisten Projekte verwenden die folgende Struktur:

 . +-- IncomingModels | +-- DataTypeInterface | +-- DataType1 | +-- DataType2 | +-- DataType3 +-- Filters | +-- FilterInterface | +-- FilterValidDataType2 +-- Processors | +-- ProcessorInterface | +-- ConvertDataType1ToDto1 | +-- ConvertDataType2ToDto2 +-- OutgoingModels +-- DtoInterface +-- Dto1 +-- Dto2 

Das heißt, die Daten sind nach Funktionen strukturiert (alle Eingabemodelle befinden sich in einem Verzeichnis oder Paket, alle Filter befinden sich in einem anderen Verzeichnis oder Paket usw.).

Es funktioniert großartig. Wenn Sie jedoch nach Daten strukturieren, ist es viel einfacher, das Projekt in kleinere zu unterteilen, da Sie möglicherweise irgendwann fast alles wie bisher ausführen müssen, mit nur geringfügigen Unterschieden.

 . +-- Base | +-- IncomingModels | | +-- DataTypeInterface | +-- Filters | | +-- FilterInterface | +-- Processors | | +-- ProcessorInterface | +-- OutgoingModels | +-- DtoInterface +-- Data1 | +-- IncomingModels | | +-- DataType1 | +-- Processors | | +-- ConvertDataType1ToDto1 | +-- OutgoingModels | +-- Dto1 ... 

Jetzt können Sie ein Modul erstellen, das nur mit Data1 funktioniert, ein anderes Modul, das nur mit Data2 funktioniert usw. Und dann können Sie sie in isolierte Module aufteilen.

Wenn Sie ein anderes Projekt erstellen müssen, das ebenfalls Data1 enthält und mit Data3 arbeitet, können Sie den größten Teil des Codes im Data1-Modul wiederverwenden.

Erstellen Sie Bibliotheken


Ich habe oft gesehen, wie Entwickler entweder Mega-Repositorys mit unterschiedlichen Projekten erstellen oder unterschiedliche Zweige beibehalten, nicht um eine temporäre Umgebung für den späteren Beitritt zum Hauptteil zu schaffen, sondern einfach, um das Projekt in kleinere Teile aufzuteilen (über das Aufteilen in) Stellen Sie sich vor, ich verwende anstelle eines neuen Projekts, das den Typ Data1 wiederverwendet, einen Zweig mit einer völlig anderen Hauptfunktion und einem anderen Data3-Typ.

Warum nicht häufig verwendete Teile Bibliotheken zuordnen, die in verschiedenen Projekten verbunden werden können?

Meistens liegt der Grund darin, dass die Benutzer nicht wissen, wie Bibliotheken erstellt werden sollen, oder sich Sorgen darüber machen, wie diese Bibliotheken in Abhängigkeitsquellen "veröffentlicht" werden können, ohne sie preiszugeben (es ist also nicht besser zu verstehen, wie Ihr Projektmanagement-Tool Abhängigkeiten erhält damit Sie Ihr eigenes Abhängigkeits-Repository erstellen können?).

Lernen Sie zu überwachen


In einem früheren Leben habe ich viele Metriken hinzugefügt, um zu verstehen, wie sich das System verhält: wie schnell es kam, wie schnell es ging, wie viel zwischen Eingabe und Ausgabe lag, wie viele Aufgaben verarbeitet wurden ...

Dies gibt wirklich eine gute Vorstellung vom Verhalten des Systems. Verringert sich die Geschwindigkeit? Um zu verstehen, kann ich überprüfen, welche Daten in das System gelangen. Ist die Geschwindigkeitsreduzierung irgendwann normal?

Tatsache ist, dass es ohne weitere Überwachung ziemlich seltsam ist, herauszufinden, wie „gesund“ das System ist. Ein Gesundheitscheck im Stil "Reagiert er auf Anfragen" ist nicht mehr geeignet.
Durch frühzeitiges Hinzufügen der Überwachung können Sie besser verstehen, wie sich das System verhält.

Verwenden Sie Konfigurationsdateien


Stellen Sie sich vor: Sie haben eine Funktion geschrieben, für die Sie einen Wert übergeben müssen, damit die Verarbeitung gestartet werden kann (z. B. die Konto-ID auf Twitter). Dann müssen Sie dies jedoch mit zwei Werten tun, und Sie rufen die Funktion einfach erneut mit einem anderen Wert auf.

Es ist besser, Konfigurationsdateien zu verwenden und die Anwendung nur zweimal mit zwei verschiedenen Konfigurationen auszuführen.

Befehlszeilenoptionen sehen seltsam aus, sind aber nützlich


Wenn Sie etwas in Konfigurationsdateien übertragen, können Sie Ihren Benutzern das Leben erleichtern und die Möglichkeit hinzufügen, die Datei auszuwählen und zu öffnen.

Heutzutage gibt es für jede Sprache Bibliotheken, die mit Optionen für die Befehlszeile arbeiten. Sie helfen Ihnen beim Erstellen eines guten Dienstprogramms, indem sie eine Standardbenutzeroberfläche für alles bereitstellen.

Nicht nur Funktionszusammensetzungen, sondern auch Anwendungszusammensetzungen


Unix verwendet dieses Konzept: "Anwendungen, die eines tun und es gut machen."

Ich sagte, dass Sie eine Anwendung mit zwei Konfigurationsdateien verwenden können. Und wenn Sie Ergebnisse aus beiden Anwendungen benötigen? Dann können Sie eine Anwendung schreiben, die die Ergebnisse der Sekunde liest und alles zu einem gemeinsamen Ergebnis kombiniert.

Beginnen Sie auch bei der Verwendung der Anwendungszusammensetzung dumm


Die Zusammensetzung von Anwendungen kann sich zu Microservices entwickeln (was gut ist), sie erfordern jedoch ein Verständnis dafür, wie Anwendungen über das Netzwerk (Protokolle und dergleichen) miteinander "kommunizieren".
Sie müssen nicht damit beginnen. Anwendungen können viel einfacher aus Dateien schreiben und lesen. Sie werden später über Remote-Interaktion nachdenken, wenn Sie das Netzwerk verstehen.

Lassen Sie Optimierungen für Compiler


, . «, », , « , ».

, . , .

, , , . , . . . , .


, , . Lisp, . , Python yield , , , . , , , , .



, , . , « », « » ..

, .

,


, .

, , «»: , , , . , , . , , , .

, , . , .


, . (« ?»), .

… Google


, . , Google , . , , Google , .

C/C++ — K&R


. :)

Python — PEP8


PEP8. , .


, ? sleep() .

? ?

, . sleepForSecs sleepForMs , , sleep .

, .

«Zen of Python», .

,


, . , - . - , , , .

« , » — .

: , — . , .

, Java , Rust. , Spring , ++.


, — , «» .

, .


, , - .

— , — .

« , »


« » « ». , , , , .

, .

,


, , , , .

.

( «»), , , . , AWS SQS ( ), , , RabbitMQ.

- , , , .

Persönlich


,


, . , . , .

( , ). , , , .

,


- , , . , , , , .

, . , , , « » « , ».

, .


«». , . , . , , . , .

: «, , , , ». , .

.


. - . «» «».

, , , . , .

, ,


. , , - , .

Tu das nicht.

- , .


- , . , .

, . .

- ,


: - , . , .

«, , » — , .


, , . . , - . . .

, , . , , , - . , , .

,


« ».

- , , , . : « , , ».

.


, , , . .

, .

«»


«» — . , - « », - .

, , , . , , , .

.

, , «»


. - : «, , ?»

, . , , (, , ).

, —


, -, , , , ( ).

… , - , , « !».

:


«» , , , , . , , .

, /, .

, .

- .

« » « »


: - , , , .

« » — , .

.

,


, , - , .

- .

, .

, , .

, , , .

… .

IT


.

, , 15 , 3-4 .

.

.

, , , - , , , , , , .


. , , URL, .

Trello — ,


« , », .

,


, « , », « , ».

. . , - .

, .

.

, , .


, . , « ». - « », , .

. .


Github «, » . , - .

.

: Python, , Java Python, .

«, »


, , , «, ».

- , , - . , .

Source: https://habr.com/ru/post/de456862/


All Articles