window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = Fenster if (w.LeadBooster) { console.warn('LeadBooster existiert bereits') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() thecodest, Author at The Codest - Page 8 of 18

Daher ist es für manche unverständlich, dass Refaktorierung ist eigentlich ein Bereich der Programmierung, und es ist auch ein sehr wichtiger Teil der Arbeit des Programmierers. Der Code entwickelt sich ständig weiter, er wird so lange geändert, wie die Möglichkeit besteht, neue Funktionen hinzuzufügen. Er kann jedoch eine Form annehmen, die es nicht mehr erlaubt, neue Funktionalitäten effektiv hinzuzufügen, und es wäre einfacher, das gesamte Programm neu zu schreiben.

Was ist Refactoring?

In der Regel hört man als Antwort, dass die Struktur des Codes durch Anwendung einer Reihe von Refactoring-Transformationen geändert wird, ohne das beobachtbare Verhalten des Codes zu beeinflussen. Das ist richtig. Kürzlich bin ich auch auf eine Definition von Martin Fowler in seinem Buch "Verbesserung der Gestaltung von bestehendem Code" wo er beschreibt Refaktorierung als "große Veränderungen in kleinen Schritten vornehmen". Er beschreibt Refaktorierung als eine Änderung des Codes, die sich nicht auf den Betrieb auswirkt, aber er betont, dass dies in kleinen Schritten geschehen muss.

In dem Buch wird auch befürwortet, dass Refaktorierung die Funktionsweise des Codes nicht beeinträchtigt und darauf hinweist, dass sie sich zu keinem Zeitpunkt auf das Bestehen der Tests auswirkt. Es wird Schritt für Schritt beschrieben, wie man sicher durchführen kann Refaktorierung. Ich mochte sein Buch, weil es einfache Tricks beschreibt, die man bei der täglichen Arbeit anwenden kann.

Warum brauchen wir Refactoring?

 Meistens braucht man sie, wenn man eine neue Funktion einführen will und der Code in seiner aktuellen Version dies nicht zulässt oder es ohne Änderungen am Code schwieriger wäre. Sie ist auch dann nützlich, wenn das Hinzufügen weiterer Funktionen zeitlich unrentabel ist, d. h. es wäre schneller, den Code von Grund auf neu zu schreiben. Ich glaube, es wird manchmal vergessen, dass Refaktorierung kann den Code sauberer und lesbarer machen. Martin schreibt in seinem Buch, wie er Refactoring durchführt, wenn er unangenehme Gerüche im Code wahrnimmt und, wie er es ausdrückt, "Es bleibt immer Raum für das Bessere". Und hier hat er mich überrascht, indem er Refactoring als ein Element der alltäglichen Codearbeit sieht. Für mich sind die Codes oft unverständlich, sie zu lesen ist eine kleine Erfahrung, da der Code oft unintuitiv ist.

Ein gut konzipiertes Programm zeichnet sich dadurch aus, dass es ModularitätDank der Modularität ist es ausreichend, nur einen kleinen Teil des Codes zu kennen, um die meisten Änderungen vorzunehmen. Die Modularität macht es auch neuen Mitarbeitern leichter, sich einzuarbeiten und die Arbeit effizienter zu gestalten. Um diese Modularität zu erreichen, müssen zusammengehörige Programmelemente gruppiert werden, wobei die Zusammenhänge verständlich und leicht zu finden sein müssen. Es gibt keine allgemeingültige Faustregel dafür, wie dies zu bewerkstelligen ist. Je mehr man weiß und versteht, wie der Code funktionieren soll, desto besser kann man die Elemente gruppieren, aber manchmal muss man auch testen und überprüfen.

Eine der Regeln für das Refactoring in YAGNIist ein Akronym für "You Aren't Gonna Need It" und leitet sich ab von eXtreme Programmierung (XP) hauptsächlich verwendet in Agil Software-Entwicklung Teams. Lange Rede kurzer Sinn, YAGNI besagt, dass nur aktuelle Dinge getan werden sollten. Das bedeutet im Grunde, dass selbst wenn etwas in der Zukunft benötigt werden könnte, es nicht jetzt gemacht werden sollte. Aber wir können auch weitere Erweiterungen nicht unterdrücken, und hier wird die Modularität wichtig.

Wenn Sie über Refaktorierungmuss eines der wichtigsten Elemente, nämlich die Tests, erwähnt werden. Unter Refaktorierungmüssen wir wissen, dass der Code noch funktioniert, denn Refaktorierung ändert nicht die Funktionsweise, sondern die Struktur, so dass alle Tests bestanden werden müssen. Es ist am besten, nach jeder kleinen Änderung Tests für den Teil des Codes durchzuführen, an dem wir gerade arbeiten. Dadurch erhalten wir eine Bestätigung, dass alles so funktioniert, wie es sollte, und es verkürzt die Zeit des gesamten Vorgangs. Das ist es, worüber Martin in seinem Buch spricht - führen Sie so oft wie möglich Tests durch, um nicht einen Schritt zurückzutreten und Zeit mit der Suche nach einer Transformation zu verschwenden, die etwas kaputt gemacht hat.

Code-Refactoring Ohne Tests ist es mühsam, und die Wahrscheinlichkeit, dass etwas schief geht, ist groß. Wenn es möglich ist, wäre es am besten, zumindest einige grundlegende Tests hinzuzufügen, die uns ein wenig Gewissheit geben, dass der Code funktioniert.

Die unten aufgeführten Transformationen sind nur Beispiele, aber sie sind bei der täglichen Programmierung sehr hilfreich:

Beispiel

Dies ist ein Artikel über Refaktorierung und ein Beispiel wird benötigt. Ich möchte im Folgenden ein einfaches Refactoring-Beispiel mit der Verwendung von Überschreiben der verschachtelten Anweisung und Ersetzung des Polymorphismus für bedingte Anweisungen. Nehmen wir an, wir haben eine Programmfunktion, die einen Hash mit Informationen darüber zurückgibt, wie man Pflanzen im wirklichen Leben gießt. Diese Informationen würden wahrscheinlich im Modell stehen, aber in diesem Beispiel haben wir sie in der Funktion.

def bewaesserung_info(pflanze)
     result = {}
     if plant.is_a? Sukkulent || plant.is_a? Kaktus
         result = { water_amount: "Ein bisschen" , how_to: "Von unten", wässern_dauer: "2 Wochen" }
     elsif plant.is_a? Alocasia || plant.is_a? Maranta
         result = { water_amount: "Große Menge", how_to: "Wie Sie es wünschen", watering_duration: "5 Tage" }
     elsif plant.is_a? Peperomia
         result = { water_amount: "Dicent amount",
             how_to: "Von unten! Sie mögen kein Wasser auf den Blättern",
             wässern_dauer: "1 Woche" }
     sonst
         result = { water_amount: "Dicent amount",
             how_to: "Wie Sie wünschen",
             wässern_dauer: "1 Woche"
             }
     end
     Ergebnis zurückgeben
 end

Die Idee ist, sich zu ändern, wenn man zurückkehrt:

if plant.isa? Sukkulent || plant.isa? Kaktus

     result = { wateramount: "Ein bisschen" , howto: "Von unten",

An

return { water_amount: "Ein kleines bisschen" , how_to: "Von unten",watering_duration: "2 Wochen" } if plant.is_a? Sukkulente || plant.is_a? Kaktus

Rückgabe { WasserMenge: "Ein bisschen", wiezu: "Von unten", BewässerungDauer: "2 Wochen" } if plant.isa? Sukkulent || plant.is_a? Kaktus

Und so geht es weiter, bis wir zu einer Funktion kommen, die wie folgt aussieht:

def bewaesserung_info(pflanze)

return result = { wateramount: "Ein wenig" , howto: "Von unten", wateringduration: "2 Wochen" } if plant.isa? Sukkulent || plant.is_a? Kaktus

return result = { wateramount: "Große Menge", howto: "Wie Sie wollen", Bewässerungsdauer: "5 Tage" } if plant.isa? Alocasia || plant.is_a? Maranta

return result = { water_amount: "Dicent amount",

          howto: "Von unten! Sie mögen kein Wasser auf den Blättern",
          wateringduration: "1 Woche" } if plant.is_a? Peperomia

return result = { water_amount: "Dicent amount",

          how_to: "Wie Sie wünschen",

          wässern_dauer: "1 Woche"

          }

end

 Ganz am Ende hatten wir bereits ein Ergebnis. Und eine gute Angewohnheit ist es, dies Schritt für Schritt zu tun und jede Änderung zu testen. Sie könnten diesen if-Block durch einen switch case ersetzen und es würde sofort besser aussehen, und Sie müssten nicht jedes Mal alle ifs überprüfen. Das würde dann so aussehen:

def bewaesserung_info(pflanze)

swich plant.class.to_string

case Sukkulent, Kaktus

     { wateramount: "Ein wenig" , howto: "Von unten", watering_duration: "2 Wochen" }

Fall Alocasia, Maranta

     { wateramount: "Große Menge", howto: "Wie Sie möchten", watering_duration: "5 Tage" }

Fall Peperomia

     { water_amount: "Dicent amount",

          how_to: "Von unten! Sie mögen kein Wasser auf den Blättern",

          watering_duration: "1 Woche" }

sonst

     { water_amount: "Dicent amount",

            how_to: "Wie Sie wünschen",

       watering_duration: "1 Woche" }

end

end

Und dann können Sie die Ersetzen des Polymorphismus für bedingte Anweisungen. Damit soll eine Klasse mit einer Funktion erstellt werden, die den richtigen Wert zurückgibt und sie an die richtige Stelle setzt.

Klasse Sukkulent

...

def bewaesserung_info()

     return { wateramount: "Ein bisschen" , howto: "Von unten", watering_duration: "2 Wochen" }

end

end

Klasse Kaktus

...

def bewaesserung_info()

     return { wateramount: "Ein bisschen" , howto: "Von unten", watering_duration: "2 Wochen" }

end

end

Klasse Alocasia

...

def bewässerung_info

     return { wateramount: "Große Menge", howto: "Wie Sie wollen", watering_duration: "5 Tage" }

end

end

Klasse Maranta

...

def bewässerung_info

     return { wateramount: "Große Menge", howto: "Wie Sie wollen", watering_duration: "5 Tage" }

end

end

Klasse Peperomia

...

def gießen_info

     return { water_amount: "Dicent amount",

      how_to: "Von unten! Sie mögen kein Wasser auf den Blättern",

      watering_duration: "1 Woche" }

end

end

Klasse Plant

...

def bewässerung_info

     return { water_amount: "Dicent amount",

              how_to: "Wie Sie wünschen",

              watering_duration: "1 Woche" }

end

end

Und in der Hauptfunktion watering_infofunction wird der Code wie folgt aussehen:

def bewaesserung_info(pflanze)

    Pflanze.map(&:Bewässerungsinfo)

end

Natürlich kann diese Funktion entfernt und durch ihren Inhalt ersetzt werden. Mit diesem Beispiel wollte ich die allgemeine Refactoring-Muster.

Zusammenfassung

Refaktorierung ist ein großes Thema. Ich hoffe, dieser Artikel war ein Anreiz, mehr zu lesen. Diese Refactoring-Fähigkeiten helfen Ihnen, Ihre Fehler zu finden und Ihren Workshop für sauberen Code zu verbessern. Ich empfehle die Lektüre von Martins Buch (Improving the Design of Existing Code), das ein ziemlich grundlegendes und hilfreiches Regelwerk von Refaktorierung. Der Autor zeigt verschiedene Transformationen Schritt für Schritt mit einer vollständigen Erklärung und Motivation und Tipps, wie man Fehler zu vermeiden in Refaktorierung. Aufgrund seiner Vielseitigkeit ist es ein reizvolles Buch für Frontend- und Backend-Entwickler.

Werden Sie Junior Ruby Entwickler

Mehr lesen

GraphQL Ruby. Wie sieht es mit der Leistung aus?

Eisenbahnen und andere Transportmittel

Rails-Entwicklung mit TMUX, Vim, Fzf + Ripgrep

de_DEGerman