window.pipedriveLeadboosterConfig = { basis: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', versie: 2, } ;(functie () { var w = venster als (w.LeadBooster) { console.warn('LeadBooster bestaat al') } anders { w.LeadBooster = { q: [], on: functie (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: functie (n) { this.q.push({ t: 't', n: n }) }, } } })() thecodest, Author at The Codest - Page 8 of 18

Daarom is het voor sommigen onbegrijpelijk dat refactoring is eigenlijk een gebied van programmeren, en het is ook een zeer belangrijk onderdeel van het werk van de programmeur. De code is altijd in ontwikkeling, hij wordt aangepast zolang de mogelijkheid bestaat om nieuwe functionaliteiten toe te voegen. De code kan echter een vorm aannemen waarbij het niet langer mogelijk is om effectief nieuwe functionaliteiten toe te voegen en het eenvoudiger zou zijn om het hele programma te herschrijven.

Wat is refactoring?

Meestal is het antwoord dat je hoort dat het de structuur van de code verandert door een reeks refactoring transformaties toe te passen zonder het waarneembare gedrag van de code te beïnvloeden. Dit is waar. Onlangs kwam ik ook een definitie tegen van Martin Fowler in zijn boek "Het ontwerp van bestaande code verbeteren". waar hij beschrijft refactoring als "grote veranderingen maken in kleine stappen". Hij beschrijft refactoring als een codewijziging die geen invloed heeft op de werking, maar hij benadrukt dat het in kleine stappen moet gebeuren.

Het boek pleit er ook voor dat refactoring geen invloed heeft op de werking van de code en wijst erop dat het op geen enkel moment invloed heeft op het slagen voor de tests. Het beschrijft stap voor stap hoe je veilig refactoring. Ik vond zijn boek leuk omdat het eenvoudige trucs beschrijft die in het dagelijks werk kunnen worden gebruikt.

Waarom hebben we refactoring nodig?

 Meestal heb je het nodig wanneer je een nieuwe functionaliteit wilt introduceren en de code in de huidige versie dit niet toelaat of het moeilijker zou zijn zonder wijzigingen aan de code. Het is ook nuttig in gevallen waarin het toevoegen van meer functies tijdtechnisch niet rendabel is, dat wil zeggen, het zou sneller zijn om de code vanaf nul te herschrijven. Ik denk dat soms vergeten wordt dat refactoring kan de code schoner en leesbaarder maken. Martin schrijft in zijn boek hoe hij refactoring uitvoert als hij onaangename geuren in de code voelt en, hoe hij het zegt, "het laat altijd ruimte voor het betere". En hij verraste me hier door refactoring te zien als een onderdeel van het dagelijkse codewerk. Voor mij zijn de codes vaak onbegrijpelijk, het lezen ervan is een beetje een ervaring omdat de code vaak onintuïtief is.

Het onderscheidende kenmerk van een goed ontworpen programma is zijn modulariteitwaardoor het voldoende is om slechts een klein deel van de code te kennen om de meeste wijzigingen door te voeren. Modulariteit maakt het ook makkelijker voor nieuwe mensen om in te stappen en efficiënter aan de slag te gaan. Om deze modulariteit te bereiken, moeten verwante programma-elementen worden gegroepeerd, waarbij de verbindingen begrijpelijk en gemakkelijk te vinden zijn. Er is geen eenduidige vuistregel over hoe dit gedaan kan worden. Naarmate je meer en meer weet en begrijpt van hoe de code zou moeten werken, kun je de elementen groeperen, maar soms moet je ook testen en controleren.

Een van de regels van refactoring in YAGNIHet is een acroniem voor 'You Aren't Gonna Need It' en komt van eXtreme Programmeren (XP) voornamelijk gebruikt in Agile softwareontwikkeling teams. Lang verhaal kort, YAGNI zegt dat alleen actuele dingen gedaan moeten worden. Dit betekent in feite dat zelfs als iets in de toekomst nodig zou kunnen zijn, het nu nog niet gedaan zou moeten worden. Maar we kunnen ook verdere uitbreidingen niet verpletteren en dit is waar modulariteit belangrijk wordt.

Als je het hebt over refactoringmoet een van de meest essentiële elementen, namelijk testen, worden genoemd. In refactoringmoeten we weten dat de code nog steeds werkt, omdat refactoring verandert niet hoe het werkt, maar de structuur, dus alle tests moeten worden doorstaan. Het is het beste om tests uit te voeren voor het deel van de code waar we aan werken na elke kleine transformatie. Het geeft ons een bevestiging dat alles werkt zoals het zou moeten en het verkort de tijd van de hele operatie. Dit is waar Martin het over heeft in zijn boek - zo vaak mogelijk testen uitvoeren om niet een stap terug te doen en tijd te verspillen aan het zoeken naar een transformatie die iets kapot heeft gemaakt.

Code refactoring Zonder testen is het lastig en er is een grote kans dat er iets fout gaat. Als het mogelijk is, zou het het beste zijn om op zijn minst wat basistests toe te voegen die ons een beetje zekerheid geven dat de code werkt.

De transformaties hieronder zijn slechts voorbeelden, maar ze zijn echt nuttig bij het dagelijkse programmeren:

Voorbeeld

Dit is een artikel over refactoring en er is een voorbeeld nodig. Ik wil hieronder een eenvoudig voorbeeld van refactoring laten zien met behulp van De geneste verklaring overschrijven en Vervanging van het voorwaardelijke instructiepolymorfisme. Laten we zeggen dat we een programmafunctie hebben die een hash teruggeeft met informatie over hoe je planten in het echt water geeft. Zulke informatie zou waarschijnlijk in het model zitten, maar voor dit voorbeeld hebben we het in de functie.

def besproei_info(plant)
     resultaat = {}
     if plant.is_a? Suculent || plant.is_a? Cactus
         resultaat = {water_hoeveelheid: "Een klein beetje " , how_to: "Vanaf de bodem", water geven_duur: "2 weken" }
     elsif plant.is_a? Alocasia || plant.is_a? Maranta
         result = {water_hoeveelheid: "Grote hoeveelheid", hoe_te: "Zoals u wilt", water geven_duur: "5 dagen" }
     elsif plant.is_a? Peperomia
         result = {water_hoeveelheid: "Dicent hoeveelheid",
             how_to: "Vanaf de onderkant! Ze houden niet van water op de bladeren",
             watergift_duur: "1 week" }
     anders
         resultaat = {water_hoeveelheid: "Dicent amount",
             how_to: "Zoals u verkiest",
             bewatering_duur: "1 week"
             }
     einde
     resultaat retourneren
 einde

Het idee is om te veranderen als terug te keren:

Als plant.isa? Suculent || plant.isa? Cactus

     result = {waterhoeveelheid: "Een beetje " , howto: "Vanaf de bodem",

Naar

return {water_hoeveelheid: "Een klein beetje " , how_to: "Vanaf de bodem" , watering_duration: "2 weken" } if plant.is_a? Suculent || plant.is_a? Cactus

return {waterhoeveelheid: "Een beetje" , hoenaar: "Vanaf de bodem",water gevenduur: "2 weken" } if plant.isa? Suculent || plant.is_a? Cactus

En zo verder tot we bij een functie komen die er als volgt uitziet:

def besproei_info(plant)

return result = {waterhoeveelheid: "Een klein beetje " , hoezo: "Vanaf de bodem", bewateringsduur: "2 weken" } if plant.isa? Suculent || plant.is_a? Cactus

return result = {waterhoeveelheid: "Grote hoeveelheid", hoezo: "Zoals u wilt", watergeefduur: "5 dagen" } if plant.isa? Alocasia || plant.is_a? Maranta

return result = {water_hoeveelheid: "Dicent amount",

          howto: "Vanaf de bodem! Ze houden niet van water op de bladeren",
          watergeefduur: "1 week" } if plant.is_a? Peperomia

return result = {water_hoeveelheid: "Dicent amount",

          how_to: "Zoals u verkiest",

          bewatering_duur: "1 week".

          }

einde

 Helemaal aan het einde hadden we al een resultaat. En een goede gewoonte is om dit stap voor stap te doen en elke verandering te testen. Je zou dit if-blok kunnen vervangen door een switch-case en dan ziet het er meteen beter uit en hoef je niet elke keer alle ifs te controleren. Het zou er dan zo uitzien:

def besproei_info(plant)

swich plant.class.to_string

geval Suculent, Cactus

     {waterhoeveelheid: "Een beetje " , hoezo: "Vanaf de bodem", water geven_duur: "2 weken" }

geval Alocasia, Maranta

     {waterhoeveelheid: "Grote hoeveelheid", hoezo: "Zoals u wilt", water geven_duur: "5 dagen" }

geval Peperomia

     {water_hoeveelheid: "Dicent hoeveelheid",

          how_to: "Vanaf de onderkant! Ze houden niet van water op de bladeren",

          watering_duration: "1 week" }

anders

     {water_bedrag: "Dicent amount",

            how_to: "Zoals u verkiest",

       bewatering_duur: "1 week" }

einde

einde

En dan kun je de Het voorwaardelijke instructiepolymorfisme vervangen. Dit is om een klasse te maken met een functie die de juiste waarde teruggeeft en ze op de juiste plaats zet.

Klasse Suculent

...

def watergift_info()

     return {waterhoeveelheid: "Een beetje " , hoezo: "Vanaf de bodem", watering_duration: "2 weken" }

einde

einde

klasse Cactus

...

def bewatering_info()

     return {waterhoeveelheid: "Een klein beetje " , howto: "Vanaf de bodem", watering_duration: "2 weken" }

einde

einde

klasse Alocasia

...

def besproeiing_info

     return {wateramount: "Grote hoeveelheid", howto: "Zoals u verkiest", watering_duration: "5 dagen" }

einde

einde

klasse Maranta

...

def besproeiing_info

     return {wateramount: "Grote hoeveelheid", howto: "Zoals u verkiest", watering_duration: "5 dagen" }

einde

einde

klasse Peperomia

...

def watergift_info

     return {water_bedrag: "Dicent amount",

      how_to: "Vanaf de onderkant! Ze houden niet van water op de bladeren",

      watering_duration: "1 week" }

einde

einde

Klasse Plant

...

def besproeiing_info

     return {water_bedrag: "Dicent amount",

              how_to: "Zoals u verkiest",

              bewatering_duur: "1 week" }

einde

einde

En in de hoofdwatering_infofunctie ziet de code er als volgt uit:

def besproei_info(plant)

    plant.map(&:besproeiing_info)

einde

Natuurlijk kan deze functie worden verwijderd en vervangen door zijn inhoud. Met dit voorbeeld wilde ik de algemene patroon van refactoring.

Samenvatting

Refactoring is een groot onderwerp. Ik hoop dat dit artikel een stimulans was om meer te lezen. Deze vaardigheden in refactoring u helpen bugs te vinden en uw schone code-workshop te verbeteren. Ik raad aan om het boek van Martin te lezen (Improving the Design of Existing Code), dat een vrij basale en nuttige verzameling regels bevat van refactoring. De auteur toont verschillende transformaties stap voor stap met een volledige uitleg en motivatie en tips om fouten te vermijden in refactoring. Door zijn veelzijdigheid is het een heerlijk boek voor frontend en ontwikkelaars van backends.

Word Junior Ruby Ontwikkelaar

Meer lezen

GraphQL Ruby. Hoe zit het met de prestaties?

Rails en andere transportmiddelen

Rails ontwikkelen met TMUX, Vim, Fzf + Ripgrep

nl_NLDutch