Codierungsstile bei Verwendung mehrerer unterschiedlicher Bibliotheken

9

Ich arbeite an C ++ - Code, der mehrere Bibliotheken verwendet, einschließlich einiger C-Bibliotheken, die alle unterschiedliche Codierungsstile haben. Es wird Open Source sein, sobald es ein brauchbares Stadium erreicht. Was würde die geringste Verwirrung für einen kurzfristigen Mitarbeiter verursachen, der den Code überprüft, um einen Fehler zu beheben oder eine Funktion hinzuzufügen?

  • Haben Sie einen einheitlichen Codierungsstil in der gesamten Anwendung, auch wenn dieser gelegentlich nicht dem typischen Codierungsstil der verwendeten Bibliotheken entspricht.
  • Wenn eine Bibliothek in einem bestimmten Modul häufig verwendet wird, müssen Sie den typischen Codierungsstil dieser Bibliothek (dh den Codierungsstil, der im eigenen Code und in der Dokumentation der Bibliothek verwendet wird) in diesem Modul einhalten.

Meiner Meinung nach wird Letzteres es Experten in dieser bestimmten Bibliothek erleichtern, einmalige Beiträge zu leisten, und es einfacher machen, Tutorial- / Beispielcode während der Entwicklung einzubeziehen. Es macht jedoch auch den Codierungsstil in der gesamten Anwendung inkonsistent. Was sind die Vor- und Nachteile jedes Ansatzes?

Karl Bielefeldt
quelle
4
Wäre es möglich, dieses Problem zu vermeiden, indem Sie alle Bibliotheken in Ihre eigenen benutzerdefinierten Abstraktionen einschließen? Ihr eigener Code und Ihre eigenen Abstraktionen könnten dann einem einzigen Codierungsstil folgen.
MetaFight
Ich abstrahiere viel von diesen Bibliotheken. Die Frage ist, welcher Codierungsstil innerhalb der Abstraktion verwendet werden soll.
Karl Bielefeldt
6
Ah. Ich bin hier kein Experte, aber es scheint, als wäre es am besten, die Konvention der Bibliothek selbst zu verwenden. Die Verwendung einer nicht übereinstimmenden Konvention klingt nach einem Wartungsalptraum. Und solange der Stil der Bibliothek in der Klasse / dem Modul enthalten ist, die ihn abstrahiert, gehe ich davon aus, dass dies in Ordnung wäre. Auch hier bin ich kein Profi, aber dies scheint eine gute Balance zu sein, die Ihnen eine einfachere Pflege Ihrer Abstraktionen ermöglicht und es Ihnen ermöglicht, Ihren eigenen Stil im Rest der Anwendung zu haben.
MetaFight
1
Manchmal können solche Abstraktionen etwas hässlich werden. Geben Sie Ihr Bestes, um sie unabhängig von den verwendeten Konventionen sauber zu halten. Stellen Sie jedoch vor allem sicher, dass die API, die Sie aus der Abstraktion präsentieren, von ausreichender Qualität ist, damit Sie nicht zurückkehren müssen Wenn Sie sich in die Abstraktion einmischen, können die Verbraucher problemlos mit Ihren Abstraktionen konsistent arbeiten, um sicherzustellen, dass ihr Code nicht zu einem Chaos wird, wie es in Ihren Abstraktionen der Fall sein könnte. Kurz gesagt, es gibt keine gute Antwort, aber solange Ihre Abstraktionen gute APIs enthalten, verhindern Sie zumindest, dass sich das Problem an ihnen vorbei ausbreitet.
Jimmy Hoffa
1
Was genau meinst du mit "Codierungsstil" - einfache Dinge wie die Verwendung von_underscores / camelCase / PascalCase und der Position der Klammern oder komplexere Dinge wie Klassen- / Methoden- / Funktionslayout und imperativer / funktionaler Stil?
Izkata

Antworten:

10

Ich denke, es hängt davon ab, wie groß das Gesamtprojekt sein wird.

Nehmen wir an, Sie haben ein 1-Mloc-Projekt. Für ein so großes Projekt ist es unwahrscheinlich, dass eine einzelne Person ein "Experte" in allen beteiligten Bereichen ist. In diesem Fall würde ich mich also an vorhandene Codestile für jede Hauptkomponente halten. Neue Entwickler werden einen Bereich auswählen, dies lernen und es ist unwahrscheinlich, dass sie viele andere Komponenten sehen, die möglicherweise andere Codestile haben.

Wenn das Projekt viel kleiner ist, wo es ist wahrscheinlich Individuen haben die gesamte Code - Basis zu verstehen, dann würde ich mit , dass ein dominanten Code - Stil und Stick holen. In diesem Fall halte ich die Konsistenz über das gesamte Projekt für sinnvoller, da neue Entwickler wahrscheinlich in allen Bereichen des Projekts arbeiten werden.

Mittelgroße Projekte sind vielleicht am schwierigsten zu treffen. In diesem Fall müssen Sie die Kosten für jeden Ansatz abwägen und entscheiden, welcher Ansatz Ihrer Meinung nach langfristig am kostengünstigsten ist. Die Herausforderung besteht darin, dass mittelgroße Projekte in der Regel gerade so weit gewachsen sind, dass ein vollständiges Refactoring des Stils unerschwinglich teuer erscheint. Vielleicht möchten Sie einen zweiten Blick auf die Codebaumstruktur werfen, um zu sehen, ob Dinge angeordnet werden können, um bestimmte Codestile zu gruppieren.

In jedem Fall sollte die endgültige Entscheidung bei dem Team liegen, dem Sie angehören und das dieses Paket zusammenstellt.


Einige der Ausreißer, die meine Argumentation von oben verschieben könnten:

  • Wenn eines oder mehrere der Module einen grausamen Stil haben, macht es keinen Sinn, dies auch bei einem größeren Projekt beizubehalten. Ja, Stil ist subjektiv, aber wenn Sie und Ihre Projektkollegen die Art und Weise, wie bestimmte Bereiche fließen, wirklich, wirklich nicht mögen, dann zerstören Sie den alten Stil und geben Sie ihm einen besseren.

  • Wenn alle Stile relativ nahe beieinander liegen, ist es möglicherweise genauso einfach, "Hier ist der neue Weg" zu deklarieren und diesen für alle neuen Codes und wichtigen Refactorings zu verwenden. Dies kann Bewertungen ein wenig schmerzhaft machen, aber meiner Erfahrung nach sind die meisten Leute ziemlich fähig, sich an diesen Ansatz anzupassen. Es bietet auch ein verräterisches Zeichen, wo sich der alte Code befindet.

  • Manchmal wird der Stil aufgrund neuer Funktionen geändert, die der Sprache hinzugefügt wurden. C ++ hat im Laufe der Jahre eine Reihe von Funktionen übernommen. Es kann sinnvoll sein, den älteren Stil nach Bedarf auf einen neueren Stil umzugestalten, der diese Funktionen nutzt.

  • Einige Bibliotheken haben möglicherweise einen besonders idiomatischen Ansatz oder Stil. In diesem Fall würde ich mich an diesen Stil für diese Bibliothek halten, auch wenn er möglicherweise mit dem Rest des Projekts in Konflikt steht. Hier soll die Wahrscheinlichkeit erhöht werden, dass jemand, der frobnosticatorsan anderen Projekten arbeitet, auch an Ihrem Projekt arbeitet.


In einigen Kommentaren wurden imperative und objektorientierte Stile als Überlegung erwähnt.

Module, die in einem bestimmten Stil "schwer" sind, sollten dies wahrscheinlich auch bleiben, wenn das Modul mittelgroß oder größer ist. Ich habe mit den drei Hauptstilen (imperativ, objektiv und funktional) gearbeitet und schwere imperative Stile in einen OO-Stil umgestaltet. Bei einer mittleren oder größeren Codemenge kann das Refactoring (ausnahmsweise) schwierig sein. Meine Erfahrung war verwirrend, weil ich keine Werkzeugunterstützung hatte, um beim Refactoring zu helfen.

Ich würde mir vorstellen, dass es eine hohe Korrelation zwischen den stark zwingend gestalteten Modulen und diesen Modulen gibt, die für bestimmte Entwicklungsnischen idiomatisch sind, was auf den letzten Punkt zurückgeht, den ich mit Ausreißern angesprochen habe. So jede Modul , das Sie für diese Funktionalität finden würde , wie das aussehen wird, und Sie wollen die Experten dieser Domäne zu leicht als auch der Lage sein , an Ihrem Projekt arbeiten. Aber wenn es Optionen gibt und Ihr Team den Stil dieses Moduls nicht mag, würde ich die Optionen untersuchen.

Ebenso habe ich mit einem Modul im Heavy-OO-Stil gearbeitet, bei dem die OO-Prinzipien zu weit gegangen sind und falsch verwendet wurden. Beispielsweise wurden Schnittstellen als Ersatz für die Mehrfachvererbung verwendet. Und wie zu erwarten war, war es eine grobe Implementierung. Ich konnte vernünftige Fortschritte bei der Überarbeitung dieses Moduls erzielen, habe diesen Ansatz jedoch letztendlich aufgegeben, da ich stattdessen bessere Pakete gefunden habe.


quelle
Das ist ein guter Weg, um es auszudrücken. Ähnliche Projekte gibt es rund 300 KLOC.
Karl Bielefeldt
3

Klingt so, als wären mehrere Ebenen zu berücksichtigen, zumindest:

  1. Die vorhandenen Bibliotheken und etwaige Änderungen daran.
  2. Neuer Unit-Test-Code für diese Bibliotheken.
  3. Die Abstraktionsschicht.
  4. Die von der Abstraktionsschicht präsentierte API.
  5. Beispiel- und Testcode unter Verwendung der Abstraktionsschicht.

Ich gehe davon aus, dass es nicht sinnvoll ist, den gesamten Code von vornherein auf einen gemeinsamen Stil umzugestalten - wenn dies der Fall wäre, hätten Sie die Frage nicht gestellt.

Jeder nacheinander aufnehmen:

  1. Für die vorhandene Codebasis möchten Sie sich wahrscheinlich an diesen Stil halten.
  2. Der neue Unit-Test-Code für vorhandenen Code befindet sich in einer Grauzone, insbesondere abhängig davon, wie stark er in älteren Code integriert ist. Aber höchstwahrscheinlich würde ich versuchen, es im "bevorzugten Stil" zu machen.
  3. Der neue Code in der Abstraktionsschicht. Indem sichergestellt wird, dass dies wirklich eine separate Codeebene ist, sollte es keine Schwierigkeiten geben, einen bevorzugten Stil zu verwenden, selbst wenn der Code viel mit einem oder mehreren Legacy-Stilen zu tun hat. Der meiste Code muss mit anderen Stilen kompatibel sein, und ich habe dies nie als Problem empfunden.
  4. Offensichtlich erfordert die API selbst die meisten Überlegungen und erfüllt die maximalen Usability-Anforderungen.
  5. Jeder Beispiel- oder Testcode sollte ebenfalls im bevorzugten Stil geschrieben werden können. Abhängig von der Vollständigkeit der Abstraktion (dh ob die unteren Schichten vollständig ausgeblendet sind) kann dies einfach oder schwierig sein. Natürlich ist es eines Ihrer Hauptziele, sicherzustellen, dass zukünftiger Client-Code lesbar ist.

Einige Dinge, die ich persönlich gefunden habe, sind die mit einer großen Legacy-Codebasis:

  • Das Festlegen eines bevorzugten Stils und das Erzwingen von Codeänderungen führt nicht auf magische Weise dazu, dass der gesamte alte Code in den neuen Stil migriert wird.

  • Die meisten Ingenieure tendieren dazu, den vorhandenen Stil in einer bestimmten Bibliothek (mehr oder weniger) zu codieren. Andernfalls ist viel Durchsetzung erforderlich.

  • Das Erfordernis eines bevorzugten Stils in einer Legacy-Bibliothek führt in der Regel zu einer großen Inkonsistenz des Stils in dieser Bibliothek. Für Standards, die sich ausschließlich auf die Präsentation konzentrieren, ist es im Gegensatz zur Robustheit des Codes auch schwierig, einen großen Vorteil darin zu sehen, sie zu fordern.

Als letztes Problem (etwas abseits des Themas, aber ich denke relevant) ist die Wahrheit, dass einige Ingenieure Schwierigkeiten haben, sich an einen anderen Stilstandard zu halten, als den, den sie am besten kennen. Ich empfehle dringend, das Team in Stilentscheidungen einzubeziehen und sicherzustellen, dass es ein Buy-In gibt. Wenn Sie dies getan haben, sind Sie in einer viel besseren Position, um tatsächlich einen Standard in gemischtem Code anzuwenden.

Keith
quelle
0

Ich werde @MetaFight hier zustimmen, falls Sie ein großes Projekt mit vielen Modulen von Drittanbietern entwickeln.

Lassen Sie uns Ihr Problem mit einem echten Wortproblem abbilden: " Angenommen, Sie haben einen ruhigen Lebensstil in Ihrem Haus. Sie möchten, dass Ihr Platz ruhig ist, Sie sprechen nie lauter und möchten niemals, dass ein Mitglied Ihrer Familie dies tut. Aber Sie interagieren mit vielen Jeden Tag verschiedene Leute draußen, um etwas für Ihr Haus zu bringen. Nicht unbedingt sprechen sie auch mit leiser Stimme. In diesem Fall formen Sie sich im Umgang mit solchen Leuten entsprechend. Daher ist die Schnittstelle oder der Wrapper für diese Leute nur aus Gründen der Flexibilität sehr flexibel Ihre Arbeit muss erledigt werden. "Dummes Beispiel ... lol

Mein Ziel ist es jedoch, einen Wrapper für solche Bibliotheken gemäß ihrem Codierungsstandard so zu erstellen, dass Sie diese Bibliotheken über diese Wrapper verwenden und dabei Ihren ursprünglichen Codierungsstil beibehalten.

+1 für MetaFight.

theinsaneone
quelle
Genau die richtige Lösung imo. Ich verwende Wrapper, um Code zu binden, den andere Leute auch für meine Projekte schreiben. Definieren Sie eine Schnittstelle im Voraus. Wenn sie dann implementiert wird, können Sie sie umschließen und in einer Blackbox testen.
Kieveli
1
Warum wird das herabgestimmt? Ich denke klar, es ist die beste Lösung :)
MetaFight
0

Es würde eindeutig die geringste Verwirrung verursachen, einen einzigen Codierungsstil in Ihrem Projekt zu verwenden. Der eigentliche Sinn der Verwendung eines Codierungsstils besteht darin, das Lesen und Ändern von Code zu vereinfachen.

Was den intern in einer Bibliothek verwendeten Codestil betrifft, halte ich ihn nicht für relevant. Wenn die Bibliothek zu wichtig ist, ist das Schreiben eines OO-Wrappers in Ordnung. Dies erfordert jedoch nicht, dass Sie denselben Codestil wie in den Beispielen oder Interna der Bibliothek verwenden.

Gustav Bertram
quelle