[...] niemand hat es klar geschafft, mir zu erklären, WARUM es so wichtig ist, sich auf den privaten Bereich zu beschränken, um zu verhindern, dass andere Programmierer die Konsistenz der Datenorganisation brechen.
In einem ausreichend kleinen Team mit einer ausreichend kleinen Codebasis, die wirklich gut auf gute Standards abgestimmt ist (möglicherweise nur eine Person), finden Sie häufig zuverlässige Software, die alle Daten offen lässt, damit jeder mit allen Datenfeldern in Kontakt treten kann eines struct
exponierten weit geöffneten und mit der struct
Definition weit offen für jeden, der diesen Header enthält, um darauf zuzugreifen. Murphys Gesetz gilt in diesen Fällen nicht immer.
Aber ich habe im umgekehrten Szenario einer riesigen Codebasis mit vielen Millionen LOC aus den 80er Jahren mit einem großen Team von Entwicklern aus der ganzen Welt gearbeitet, bei denen wir uns nur alle paar Monate persönlich getroffen haben, manchmal lose koordiniert kaum die gleiche Sprache sprechen, keine Codierungsstandards außer dem SDK, dem die Leute sowieso oft nicht gefolgt sind, keine Unit- / Integrationstests, SVN ohne Verzweigung verwenden und manchmal 6 Wochen ohne Code einchecken, nur um uns mit Fehlern zu bombardieren, und Erst dann verstand ich wirklich den Wert von Informationen, die Invarianten verstecken und aufrechterhalten .
Ich habe mich mit Fehlern befasst, bei denen ich das Problem nicht einmal konsistent auf meinem Computer reproduzieren konnte, und manchmal konnte keiner von uns zwischen dem gesamten Team. Und als ich endlich das vom Benutzer gemeldete Problem oder etwas, das ihm nach allen Arten von Versuch und Irrtum ähnelte, reproduzieren konnte (und der Versuch und Irrtum dauerte oft Stunden, weil die Ineffizienz unserer Software mit der Ausführung beim Debuggen gegen die Produktion am Ende des Benutzers verbunden war Daten dauerten oft mehr als 15 Minuten, nur um die Daten zum Laden zu bringen.) Ich verfolgte sie bis zu struct
einem String-Typ len
, für den eine negative Garbage-Zahl festgelegt war, z. B. eine String-Länge von -921141282
.
Das sollte niemals passieren, aber wer hat es getan? Also musste ich Speicher-Haltepunkte setzen und herausfinden, und als ich es schließlich tat, war es wie eine kaskadierende Interaktion von nicht initialisierten Variablen, die arithmetisch verwendet wurden, was letztendlich dazu führte, dass ein Zeichenfolgenfeld len
auf eine negative Müllzahl gesetzt wurde, und dieser Code hatte es nicht wurde in Jahren geändert. Es flog unter dem Radar.
Und die ganze Zeit, nachdem ich auf viele solche Fehler gestoßen war, dachte ich mir, wie viel zuverlässiger wäre unsere Software, wenn sie nur verwendet würde getters
und setters
? Getter und Setter weisen im Allgemeinen auf die schlechtesten möglichen Arten von Schnittstellendesigns hin, aber ein Setter könnte zumindest einen Assertionsfehler auslösen, wenn jemand versucht, die Länge eines Strings auf einen negativen Wert zu setzen. Wir hätten diesen Fehler Jahre fangen könnenvorher zu dem genauen Zeitpunkt, zu dem es in Sekunden eingeführt wurde, nicht der Höhepunkt stundenlanger Ermittlungsbemühungen. Und das ist nur egoistisch als Entwickler zu denken; Es deckt nicht alle Stunden der Trauer ab, die es den Benutzern und dem QA-Team hätte ersparen können. Sie wissen, dass Ihr System an einem ziemlich schlechten Ort ist, wenn Sie davon träumen, wie viel besser es sein könnte, wenn es angesichts der letzten 35 Fehler, die Sie die ganze Nacht über behoben haben, Setter und Getter verwendet.
Wir hatten sogar Fälle, in structs
denen dokumentiert wurde, dass niemand sonst auf diese Datenfelder zugreifen sollte, nur um Stellen im System zu finden, die auf diese Datenfelder zugreifen.
Dies sind also die Arten von Dingen, die Sie nur dann wirklich in vollen Zügen genießen können, wenn Sie sich diesem Worst-Case-Szenario stellen, aber Sie werden es oft tun, es sei denn, Sie haben das Glück, den Rest Ihres Lebens damit zu verbringen, an kleineren Codebasen mit gut koordinierten Teams zu arbeiten starke Kodierungsstandards.
Was ist schöner Code in C ++ [...]?
Das ist eine schwierige Frage. Ich versuche immer noch, das herauszufinden. Der größte Teil des Codes, den ich für schön halte, den ich im Laufe der Jahre geschrieben habe, oder zumindest zuverlässig und relativ zeitlos und stabil (ohne Änderungen zu benötigen / zu wollen), wurde in C und kürzlich in Lua geschrieben. Ich habe immer noch Schwierigkeiten, C ++ - Code zu schreiben, der den Test der Zeit so weit zu bestehen scheint, dass ich einige Jahre später nicht mehr darüber nachdenke und mir zumindest wünsche, ich könnte ihn ändern. Ich habe das Gefühl, dass es seit C ++ 11 einfacher geworden ist, aber ich brauche einige Jahre, um herauszufinden, wie gut mein Code überlebt, ohne dass Änderungen erforderlich sind, um dies sicher zu sagen. Für mich ist die ultimative "Schönheit" "Stabilität", wie in Code, der keine weiteren Änderungen benötigt und nicht einmal versucht, aber dennoch für die kommenden Jahre relevant und nützlich bleibt.