it-swarm.com.de

Wie führe ich neue Sprachfunktionen in einen alten Quellcode ein?

Ich habe eine Frage zum Codierungsstil. In meinem Beispiel ist es Java, aber ich denke, dies kann eine allgemeine Frage in Bezug auf Sprachen sein, die sich schnell ändern.

Ich arbeite an einer Java Codebasis, die hauptsächlich für das Targeting geschrieben wurde Java 8. Der Code wurde nach Java migriert) 12. Mit Migration meine ich, dass der Code auf jdk12 ausgeführt werden kann, sodass die erforderlichen Änderungen/Ergänzungen der Bibliothek vorgenommen wurden. Die neuen Sprachfunktionen wurden jedoch noch nicht verwendet (z. B. var keyword).

Meine Frage ist, wie sollte der Ansatz aussehen, um neue Sprachelemente aus Sicht der Lesbarkeit einzuführen? Wie wichtig ist Konsistenz?

Ich habe einige mögliche Ansätze im Kopf.

  1. Neue Sprachfunktionen sollten nur in neuen Klassen verwendet werden
  2. Neue Sprachfunktionen können in neu hinzugefügten Teilen vorhandener Klassen verwendet werden (z. B. eine neue Methode), selbst wenn der Rest der Klasse nicht aktualisiert wird.
  3. Wenn neuen Teilen bestehender Klassen neue Sprachfunktionen hinzugefügt werden, sollte auch der Rest der Klasse aktualisiert werden

Ich weiß, dass diese Frage etwas schwer zu beantworten ist (als Fragen im Codierungsstil im Allgemeinen), aber ich hoffe trotzdem, dass es eine Schlussfolgerung geben wird.

12
melonT

Wenn du in Rom bist, mach wie es die Römer tun.

Es ist schön, wenn eine gesamte Codebasis einem einheitlichen Stil folgt. Dies wird jedoch seinen Stil in der Vergangenheit einfangen.

Wenn Sie von einem neuen Fangled-Stil verzaubert sind, können Sie ihn am schlimmsten zufällig auf den Code verteilen, der im alten Stil verbleibt.

Wenn Sie ein Haus in einer anderen Farbe neu streichen, tun Sie dies daher nicht nur dort, wo die Farbe beschädigt ist. Du machst es Raum für Raum.

Es ist besser, die Änderung innerhalb einer Grenze vorzunehmen. Diejenigen, die den Code lesen, sollten es leicht finden, vorherzusagen, welchen Stil sie an jedem Ort finden werden.

Das Ändern des Arbeitscode-Stils ist ein Refactoring. Refactor nicht ohne Tests. Und nicht alles auf einmal umgestalten. Machen Sie einen Raum, treten Sie zurück und fragen Sie andere, was sie denken.

Wenn Sie das alles nicht können, bleiben Sie beim alten Stil. Verwenden Sie nur neue Sprachfunktionen, die sich gut in den alten Stil einfügen.

23
candied_orange

Ich arbeite seit Version 1.1 (um 2003) mit C # und habe aus erster Hand erfahren, wie wir im Laufe der Jahre neue Sprachfunktionen in unsere wachsende Codebasis eingeführt haben. Wir haben sie einfach vorgestellt, wann immer sie verfügbar waren, und alle im Team haben begonnen, sie im Bereich des Codes zu verwenden, an dem sie gearbeitet haben.

Diese Funktionen enthalten

  • generische Sammlungen (anstelle schwach typisierter Sammlungen)

  • verbesserte Eigenschaftssyntax

  • das Schlüsselwort var

  • erweiterungsmethoden

  • funktionswerkzeuge wie Lambda-Ausdrücke, Verschlüsse usw.

  • Linq

  • async/warten

(um nur einige Beispiele zu nennen).

Beachten Sie, dass selbst in neu geschriebenem Code jede dieser Funktionen in Verbindung mit älteren Sprachfunktionen verwendet wird. Sie ersetzen nicht jede mögliche Schleife durch ein Linq-Konstrukt, nur weil Linq verfügbar ist. Sie beginnen nicht, Erweiterungsmethoden für jede Funktion zu verwenden, nur weil "Erweiterungsmethoden verfügbar sind". Und die Verwendung von var heute für jede Variablendeklaration macht Ihren Code nicht lesbarer.

Daher war die tatsächliche Erfahrung nicht so schlecht, wie die anderen Antworten vorgeben könnten - im Gegenteil. Wenn Sie in einer größeren Codebasis nicht für immer an alten, ungeschickten Konstrukten festhalten möchten, müssen Sie die neuen Konstrukte irgendwo verwenden, aber Sie können sie nicht überall einführen - und es wäre nicht einmal sinnvoll, sie überall zu verwenden. Normalerweise aktualisieren Sie Arbeitscodeabschnitte nicht auf neue Sprachkonstrukte, wenn es keinen anderen zwingenden Grund gibt. Dies führt automatisch zu einigen Abschnitten mit mehr neuen Sprachkonstrukten, einige mit weniger und einige ohne, die alle gut funktionieren und oft jahrelang nebeneinander lesbar genug sind.

Meine Empfehlung hier lautet also: überdenken Sie das nicht. Die Lesbarkeit von Code, bei dem diese Funktionen gemischt sind, ist sehr subjektiv. In einem Team, in dem jeder die alten und neuen Sprachfunktionen gut kennt, ist dies weniger problematisch, als man denkt.

18
Doc Brown

Sie fragen, wie Sie mit technischen Schulden umgehen sollen. Angenommen, die kritischen Dinge wurden erledigt (Aktualisierung des Codes für die neue Java-Version), haben die Arten von Änderungen, die Sie vornehmen möchten, keine direkten Auswirkungen auf die Benutzerbasis. Infolgedessen ist es schwierig, Produktbesitzer oder das Management dazu zu bringen, einer Investition in diese Migration zuzustimmen.

Wenn Sie ein Open Source-Projekt verwalten, müssen Sie sich nicht um diesen Verwaltungsaspekt kümmern. In diesem Fall liegt es an Ihrer Community, zu bestimmen, wie schnell Sie in die Updates investieren.

Es gibt Risiken

  • Aufgrund des Missverständnisses der Besonderheiten einer neuen Funktion können subtile Fehler auftreten, die schwer zu erkennen sind
  • Einige Funktionen können Sie dazu zwingen, die Implementierung Ihrer Bibliothek/App/Ihres Dienstes zu überdenken. Diese gezielten Umschreibungen sind mit einem sehr hohen Risiko verbunden, da sie wahrscheinlich auch die Art und Weise ändern, in der sie getestet werden
  • Das Endergebnis ist möglicherweise weniger verständlich als der Code zuvor - was einen negativen Vorteil bietet

Das Ändern Ihres Arbeitscodes ohne eine Reihe von Unit-Tests ist wie eine Gratwanderung ohne Netz. Wenn Sie sehr vorsichtig sind, kann dies getan werden, aber wenn Dinge schief gehen, können sie episch schief gehen.

Es ist immer besser, alles zu tun, um Risiken zu mindern, wenn Sie technische Schulden abbezahlen.

4
Berin Loritsch

Wenn Sie eine andere Umgestaltung/Änderung in einer Klasse durchführen, bringen Sie die gesamte Klasse so, dass sie Ihren aktuellen Codierungsrichtlinien entspricht. Vermeiden Sie inkonsistente Stile in derselben Klasse. Die Klassen sollten klein genug sein, damit Sie dies einfach und mit geringem Risiko tun können. Vermutlich wird die Klasse ohnehin getestet, wenn Sie sie ändern.

Sie können eine Änderung auf einmal auf die gesamte Codebasis anwenden, wenn sie mechanisch angewendet werden kann. Z.B. Wenn Sie entscheiden, dass var foo = Foo() besser ist als Foo foo = Foo(), können Sie dies mit einem Refactoring-Tool auf einmal ziemlich sicher auf die gesamte Codebasis anwenden.

2
JacquesB