Vor kurzem hatte ich eine Diskussion mit einem Kollegen über den Codestil. Er argumentierte, dass Ihre Verwendung von APIs und die von Ihnen verwendeten allgemeinen Muster mit dem umgebenden Code so ähnlich wie möglich sein sollten, wenn nicht mit der Codebasis als Ganzes, so wie Sie es mit dem Erscheinungsbild des Codes (geschweifte Klammern, Großschreibung usw.) tun würden. . Wenn ich beispielsweise einer DAO-Klasse in C # eine Methode hinzufüge, würde ich versuchen, LINQ zu verwenden, um meinen Code sauberer und pflegeleichter zu machen, selbst wenn keine der anderen Methoden in dieser Klasse dies verwendet. Mein Kollege würde jedoch argumentieren, dass ich es in diesem Fall nicht verwenden sollte, weil es gegen den bestehenden Stil dieser Klasse und somit schwerer zu verstehen wäre.
Zuerst fand ich seine Position ziemlich extrem, aber nachdem ich eine Weile darüber nachgedacht habe, beginne ich, seinen Standpunkt zu verstehen. Im hypothetischen LINQ-Beispiel enthält diese Klasse sie möglicherweise nicht, weil meine Kollegen mit LINQ nicht vertraut sind. Wenn ja, wäre mein Code für meine Kollegen nicht besser zu pflegen, wenn ich ihn nicht verwenden würde? Auf der anderen Seite, wenn ich wirklich glaube, dass die Verwendung einer solchen Technik zu einem saubereren Code führen würde, sollte ich sie dann nicht verwenden, auch wenn sie sich drastisch vom umgebenden Code unterscheidet?
Ich denke, der Kern der Argumentation meines Kollegen ist, dass, wenn wir alle ähnliche Funktionen in einer Codebasis auf unterschiedliche Weise implementieren und wir alle denken, dass unser Weg "am besten" ist, der Code insgesamt am Ende nur schwieriger wird verstehen. Im Moment denke ich jedoch immer noch, dass die Qualität mit der Zeit nur langsam verrottet, wenn wir dem vorhandenen Code blind folgen.
Inwieweit sind Muster Teil des Codestils, und wo sollten wir die Grenze zwischen Konstanz und Verbesserungen ziehen?
quelle
IEnumerable
eher mit s als mit einem DAO befassen sollen .Antworten:
Um eine allgemeinere Antwort zu geben:
In einem solchen Fall gibt es zwei "Best Practices" für die Programmierung, die sich widersprechen: Die Codekonsistenz ist wichtig, aber auch die Auswahl der bestmöglichen Methode, um Ihre Aufgabe zu erfüllen. Es gibt keine richtige Antwort auf dieses Dilemma. es hängt von ein paar Faktoren ab:
Wie nützlich ist der "richtige" Weg?
Wie groß ist das Problem, das durch Inkonsistenz verursacht wird?
Basierend auf dem Gleichgewicht dieser Probleme müssen Sie die richtige Wahl treffen, welche Route Sie einschlagen möchten. Ich persönlich sehe aus Gründen der Konsistenz wenig Wert in der Konsistenz und würde es vorziehen, die neuesten, besten Methoden zu verwenden, es sei denn, dies ist mit erheblichen Kosten verbunden.
Natürlich gibt es eine dritte Option: den vorhandenen Code neu zu schreiben, damit er die besten Methoden verwendet und konsistent ist. Es gibt Zeiten, in denen dies notwendig ist, jedoch mit hohen Kosten verbunden ist.
quelle
Konsequent zu bleiben hat aus meiner Sicht wenig Wert. Kontinuierliche Verbesserungen sind ein Muss.
Die Position Ihres Kollegen behindert Innovation wirklich. Das Konsistenzargument versetzt Sie in eine Situation, in der Sie beispielsweise LINQ nur verwenden können, wenn Sie den gesamten Code für die Verwendung von LINQ migrieren . Und dafür haben wir keine Zeit, oder?
Ich hätte lieber eine Inkonsistenz, wenn ein Teil des Codes noch
foreach
über ArrayLists ausgeführt wird und andere Teile LINQ verwendenIEnumerable<T>
, anstatt bis zum Ende der Zeit bei der ältesten Vorgehensweise zu bleiben.Es liegt in der Verantwortung Ihrer Kollegen, relevant zu bleiben und neue Methoden zu erlernen.
quelle
API-Konsistenz ist sehr wichtig, sowohl für öffentliche als auch für interne APIs.
Die Konsistenz der Code-Formatierung ist wichtig und sollte im Idealfall durch ein automatisches Formatierungs-Tool mit denselben Formatierungsregeln für alle erzwungen werden. Erleichtert das Leben mit gemeinsam genutzter versionskontrollierter Codebasis.
Namenskonventionen sollten konsistent sein, auch für Dinge wie lokale Variablen usw.
Statische Analyse-Tools sollten verwendet werden, um bestimmte andere Konventionen und bewährte Methoden durchzusetzen (aber befolgen Sie die Standardeinstellungen eines solchen Tools nicht blind, da die Standardeinstellungen manchmal an den Wahnsinn grenzen können) überprüfe (normalerweise mit einer Direktive in einem Kommentar) vorübergehend, ob du es rechtfertigen kannst.
Was in Funktionen / Methoden geschieht , muss abgesehen von den oben aufgeführten in keiner Weise konsistent sein, solange es sich um guten Code für sich handelt . Guter, verständlicher und gut kommentierter Code ist sehr wichtig, aber wenn Compiler und statische Analysetools davon ausgehen, dass es sich um konsistenten Code handelt, ist dies konsistent genug.
Über neue Sprachfunktionen wie LINQ (nun ja, das ist nicht gerade neu) muss nur nachgedacht werden, ob überall dort, wo der Code verwendet wird, eine ausreichend neue Version von Sprache / Bibliotheken verwendet wird. Im Zweifelsfall sollten Sie sich an Funktionen halten, von denen bekannt ist, dass sie kompatibel sind. Dies hindert Sie natürlich nicht daran, ein Versions-Upgrade im gesamten System durchzuführen, sodass Sie die neuen nützlichen Funktionen nutzen können.
Und jeder Entwickler, der mit Code arbeitet, sollte auf dem neuesten Stand sein, so dass jeder .NET-Entwickler LINQ kennen sollte, und wenn nicht, sollten sie gezwungen sein, zu ihrem eigenen Besten zu lernen (Sie wissen nie, wann Sie nach einem neuen suchen werden) Job in diesem Geschäft, aus dem einen oder anderen Grund).
quelle
Die Antwort darauf ist einfach.
Konsistenz ist von größter Bedeutung.
aber es kommt mit einer Einschränkung ...
Sie und Ihre Mitarbeiter sind wahrscheinlich besessen von der falschen Art von Konsistenz
Implementierungen sind verfügbar. Sie können je nach Qualität und Umfang der Testsuite mit unterschiedlichem Aufwand komplett überarbeitet werden. Machen Sie sich Gedanken über Dinge wie "Sollte dies eine Eigenschaft sein?", "Sollte Code nicht LINQ anstelle eines Konstrukts einer niedrigeren Ebene verwenden?" ist von zweifelhaftem Wert. Es ist sehr unterschiedlich, Messungen an den Wert der Konsistenz auf Implementierungsebene zu binden. Eine viel bessere Frage auf dieser Ebene ist "Funktioniert dieser Code wie angekündigt?". TL; DR-Implementierungskonsistenz ist der Punkt, an dem "kleine Geister" ihre Hobgoblins reizen.
Warum ist Konsistenz hier nicht so wichtig? Implementierungen haben in der Regel eine geringe Anzahl von Mitwirkenden. Die meisten Methoden werden geschrieben und nie wieder angerührt. Vom restlichen Code hat die Anzahl der Methoden, die zwei Mitwirkende haben, mit ziemlicher Sicherheit die Mehrheit. Dieses Muster setzt sich unendlich fort . In diesem Zusammenhang ist Konsistenz einfach nicht so wichtig. Wenn die Haltbarkeit des Codes ziemlich gering ist ( einige Jahre ), spielen die Vorteile einer aggressiven Konsistenz wahrscheinlich keine Rolle.
Das soll nicht heißen, dass Sie bei Ihren Implementierungen verrückt werden sollten. Es ist eher zu sagen, dass ein schönes, sauberes, einfaches Design für Ihren hypothetischen zukünftigen Betreuer um Größenordnungen wertvoller sein wird als die dumme Konsistenz der Kesselplatten von Methode zu Methode. Das bringt uns zum eigentlichen Punkt ...
APIs sind nicht verfügbar.
Dies sind alle APIs auf Code-Ebene, Webservices, SDKs usw. Diese müssen konsistent sein. Die Produktivitätsgewinne aus dieser Vielfalt von Konsistenz sind aus einer Reihe von Gründen enorm:
Integrationstests:
Wenn Sie Ihre APIs konsistent halten, können Sie eine Reihe von Integrationstests erstellen. Dadurch können Entwickler die Implementierungsdetails frei austauschen und eine sofortige Validierung durchführen. Willst du deine Arbeitskollegen auf LINQ tauschen? Laufen die Integrationstests? Es bietet auch eine Validierung bei der Vorbereitung der Produktionsaufnahme. Weil Computer schnell sind, kann ein einzelner Laptop die Arbeit von tausend Testern ausführen, die alltägliche Aufgaben ausführen. Dies ist gleichbedeutend mit einer erheblichen Erhöhung der Mitarbeiterzahl Ihres Unternehmens.
Produktivität
Wenn die APIs konsistent sind, können Sie Ratschläge zur Verwendung einer API abgeben, indem Sie einfach nachvollziehen, was Sie über die Verwendung anderer Teile der API gelernt haben. Dies liegt daran, dass die API ein natürliches, konsistentes "Look and Feel" bietet. Dies bedeutet, dass Ihr Kunde weniger Zeit für das Durchsuchen der Dokumentation benötigt. Onboarding ist einfacher und billiger. Es werden weniger Fragen an die Personen gestellt, die die API entwickelt haben. Konsistenz macht jeden zum Gewinner
Warum ist Konsistenz in diesem Szenario wichtig? Weil APIs das genau entgegengesetzte Problem von Implementierungen haben. Die Anzahl der Personen, die sie verwenden, ist in der Regel viel höher als die Anzahl der Personen, die zu ihren Implementierungen beitragen. Kleine Gewinne aus einer geringen Konsistenz werden vervielfacht und die Kosten für die Aufrechterhaltung dieser Konsistenz werden amortisiert.
Fazit
Konsistenz ist teuer. Auf den ersten Blick verringert es die Produktivität. Das schränkt Entwickler ein und macht ihnen das Leben schwerer. Sie schränkt die Art und Weise ein, wie sie ein Problem lösen können, und zwingt sie manchmal, es auf nicht optimale Weise zu lösen. Dies geschieht häufig aus Gründen, die sie nicht verstehen, schlecht verstehen oder die sie nicht kennen (Verträge, größere organisatorische oder organisationsübergreifende Richtlinien).
Raymond Hettinger hat in seinem Pycon 2015-Vortrag einige hervorragende Punkte in Bezug auf die Verwendung des PEP8-Styleguides für Teams von Python-Programmierern hervorgehoben. Er zeigte, dass die Besessenheit von stilistischer Konsistenz bei einem Teil des Codes dazu führte, dass Code-Reviewer schwerwiegende Logik- und Designfehler übersahen. Seine Hypothese lässt sich zusammenfassen, da es einfach ist, stilistische Inkonsistenzen zu finden. Es ist schwierig, die tatsächliche Qualität eines Codeteils zu bestimmen
Der Punkt hier ist kritisch. Identifizieren Sie, wo Konsistenz wichtig ist, und schützen Sie sie aggressiv. Wo es nicht wichtig ist, verschwende deine Zeit nicht. Wenn Sie keinen objektiven Weg finden, um den Wert der Konsistenz zu messen (in den oben genannten Fällen "effektive Mitarbeiterzahl", Kosten als Funktion der Produktivität), und Sie nicht nachweisen können, dass die Renditen erheblich sind, tun Sie dies wahrscheinlich nicht deine Organisation.
quelle
Die C # -Sprache entwickelt sich weiter. Wenn die Leute die Änderungen von C # 1 nicht kennen würden, würden sie Folgendes verpassen:
Dies ist nur eine kleine Auswahl allgemeiner Merkmale, die im Wikipedia-Artikel zu finden sind. Der Punkt, den ich mache, ist, dass, wenn die Entwickler nicht lernen, die Codebasis in einem Vakuum bleibt. Man würde hoffen, dass sich Ihre Entwickler kontinuierlich verbessern und die Codebasis weiterentwickelt, unterstützt von einer vollständigen Testsuite. Erinnern Sie sich, wie schlecht es mit .NET 1 war, Eigenschaften manuell zu implementieren?
Linq macht das Leben leichter. Verwenden Sie es, wo Sie können. Sie könnten Ihre Teammitglieder motivieren.
Verbesserungen sind schrittweise. Für mich macht es keinen Sinn, alten Code beizubehalten, der weniger lesbar und möglicherweise weniger wartbar ist. Ihre Teammitglieder sollten zumindest in der Lage sein, herauszufinden, was los ist, auch wenn sie es nicht schreiben können.
quelle
Sie sollten konsistent sein, aber nicht unbedingt mit dem alten Code. Das heißt, Ihr Team sollte sich auf die richtige Vorgehensweise einigen und diese verwenden, wenn neuer Code geschrieben oder wesentliche Änderungen vorgenommen werden.
Auf diese Weise profitieren Sie von den meisten Vorteilen der Konsistenz (insbesondere spielt es keine Rolle, wer den Code schreibt), können sich jedoch noch verbessern, wenn das Team einen klaren Vorteil sieht, wenn Sie die Dinge auf andere Weise erledigen.
In einer idealen Welt würden wir den gesamten alten Code neu schreiben, um ihn dem neuen richtigen Weg anzupassen. Dies ist zwar wirtschaftlich nicht tragbar, sollte aber technisch sinnvoll sein (andernfalls ist der neue Weg kein besserer) und Ihr langfristiger Plan sollte sein, ihn zu aktualisieren. Wenn sich das nicht lohnt, kümmern Sie sich nicht um den neuen Weg. Anders ausgedrückt, es muss ein klarer Vorteil für die neue Methode sein, sie für die richtige zu erklären.
quelle
Ich denke , es ist wichtig , um einen Code zu folgen Stil in einem Projekt zB. Namenskonventionen, Einrückungen usw.
Ich bin nicht einverstanden, dass Sie die Verwendung neuer Sprachkonstrukte oder Entwurfsmuster nur deshalb untersagen sollten, weil Ihre Kollegen sie nicht verstehen oder sie im Projekt noch nicht verwendet wurden.
Natürlich sollten diese Dinge gute Gründe für ihre Verwendung haben, z. Leistung oder Kürze, falls zutreffend.
quelle
Ich würde sehr vorsichtig sein, wenn ich die aktuellen Designmuster blind verfolge. Wenn es keinen nennenswerten Nachteil gibt, sollte man natürlich immer versuchen, ähnliche Muster in der gesamten Codebasis zu verfolgen.
Es ist jedoch viel zu einfach, in Situationen zu geraten, in denen die Mehrheit der Entwickler das Gefühl hat, es sei "best practice", den vorhandenen schlechten Mustern zu folgen, was zu Situationen führt, in denen gute Entwickler schlechten, nicht wartbaren Code schreiben.
Auf der anderen Seite ist die Konsistenz wichtig. Wenn es um enorme Codebasen geht, ist es äußerst nützlich, ähnliche Muster zu verwenden, damit Entwickler zwar nicht jeden Zentimeter der Codebasis lesen, aber wissen, was sie zu erwarten haben.
Aus diesem Grund ist es meiner Meinung nach am besten, Richtlinien zu erstellen und zu aktualisieren, welche Muster Entwickler befolgen sollten, wenn dies möglich ist. Auf diese Weise stimmt jeder neue Code mit anderen neuen Codes überein.
quelle
Wir haben regelmäßige, recht informelle technische Treffen, die jeder von uns abhalten kann. Wenn wir eine neue Technik finden, präsentieren wir sie beim Treffen. Sie bekommen in der Regel ein gutes Gefühl dafür, wie gut die Idee von Ihren Kollegen angenommen und verstanden wird. Dies hilft Ihnen bei der Entscheidung, ob es sinnvoll ist, es in Ihren Code aufzunehmen, hilft anderen, es zu entschlüsseln, wenn Sie dies tun, und stellt auch die Kontaktperson her, wenn andere Hilfe bei diesem Stil benötigen. Wenn niemand das Rad neu erfinden würde, würden wir immer noch Dinge auf Baumstämmen herumschleppen.
quelle