Refactoring i formørkelse

1. Oversikt

På refactoring.com leser vi at “refactoring er en disiplinert teknikk for å restrukturere en eksisterende kodekode, endre den interne strukturen uten å endre dens ytre oppførsel.”

Vanligvis vil vi kanskje gi nytt navn til variabler eller metoder, eller kanskje vi vil gjøre koden vår mer objektorientert ved å introdusere designmønstre. Moderne IDE-er har mange innebygde funksjoner som hjelper oss med å nå slike refactoring-mål og mange andre.

I denne veiledningen vil vi fokusere på refactoring i Eclipse, en gratis populær Java IDE.

Før vi begynner å refactoring, anbefales det å ha en solid serie med tester for å sjekke at vi ikke brøt noe mens vi refakturerte.

2. Gi nytt navn

2.1. Endre navn på variabler og metoder

Vi kan endre navn på variabler og metoder ved å følge disse enkle trinnene:

    • Velg elementet
    • Høyreklikk på elementet
    • Klikk på Refactor> Gi nytt navn alternativ
  • Skriv inn det nye navnet
  • trykk Tast inn

Vi kan også utføre andre og tredje trinn ved ved hjelp av hurtigtasten, Alt + Skift + R.

Når handlingen ovenfor er utført, vil Eclipse finne all bruk av elementet i filen og erstatte dem alle på plass.

Vi kan også bruke en avansert funksjon til å oppdater referansen i andre klasser ved å sveve over elementet når refaktoren er på og klikke på Alternativer:

Dette åpner en popup der vi både kan gi nytt navn til variabelen eller metoden og har muligheten til å oppdatere referansen i andre klasser:

2.2. Endre navn på pakker

Vi kan gi nytt navn til en pakke ved å velge pakkenavnet og utføre de samme handlingene som i forrige eksempel. En popup vises med en gang der vi kan gi nytt navn til pakken, med alternativer som å oppdatere referanser og gi nytt navn til underpakker.

Vi kan også gi nytt navn til pakken fra Project Explorer-visningen ved å trykke på F2:

2.3. Endre navn på klasser og grensesnitt

Vi kan gi nytt navn til en klasse eller et grensesnitt ved å bruke de samme handlingene eller bare ved å trykke F2 fra Project Explorer. Dette åpner en popup med alternativer for å oppdatere referanser, sammen med noen få avanserte alternativer:

3. Utpakking

La oss nå snakke om utvinning. Utpakking av kode betyr tar et stykke kode og flytter det.

For eksempel kan vi trekke ut kode i en annen klasse, superklasse eller grensesnitt. Vi kan til og med trekke ut kode til en variabel eller metode i samme klasse.

Eclipse gir en rekke måter å oppnå ekstraksjoner på, som vi vil demonstrere i de følgende avsnittene.

3.1. Ekstraktklasse

Anta at vi har følgende Bil klasse i kodebasen vår:

offentlig klasse bil {privat strenglisensplate; privat streng drivernavn; privat streng driverlisens; public String getDetails () {return "Car [licensePlate =" + licensePlate + ", driverName =" + driverName + ", driverLicense =" + driverLicense + "]"; } // getters og setters}

Anta at vi vil trekke ut driverinformasjonen til en annen klasse. Vi kan gjøre dette ved å høyreklikke hvor som helst i klassen og velge Refactor> Ekstraktklasse alternativ:

Dette åpner en popup der vi kan navngi klassen og velge hvilke felt vi vil flytte, sammen med noen få andre alternativer:

Vi kan også forhåndsvise koden før vi går videre. Når vi klikker OK, Eclipse vil opprette en ny klasse med navnet Sjåfør, og den forrige koden vil bli omformet til:

offentlig klasse bil {privat strenglisensplate; privat førerdriver = ny driver (); public String getDetails () {return "Car [licensePlate =" + licensePlate + ", driverName =" + driver.getDriverName () + ", driverLicense =" + driver.getDriverLicense () + "]"; } // getters og setters}

3.2. Pakk grensesnitt

Vi kan også trekke ut et grensesnitt på lignende måte. Anta at vi har følgende EmployeeService klasse:

offentlig klasse EmployeeService {public void save (Employee emp) {} public void delete (Employee emp) {} public void sendEmail (List ids, String message) {}}

Vi kan trekke ut et grensesnitt ved høyreklikke hvor som helst i klassen og velge Refactor> Extract Interface alternativ, eller vi kan bruke Alt + Skift + T. hurtigtastkommando for å få opp menyen direkte:

Dette åpner en popup der vi kan angi grensesnittnavnet og bestemme hvilke medlemmer som skal erklæres i grensesnittet:

Som et resultat av denne refactoring vil vi ha et grensesnitt IEmpService, og vår EmployeeService klasse vil også bli endret:

offentlig klasse EmployeeService implementerer IEmpService {@Override public void save (Employee emp) {} @Override public void delete (Employee emp) {} public void sendEmail (List ids, String message) {}}

3.3. Trekk ut superklassen

Anta at vi har en Ansatt klasse som inneholder flere eiendommer som ikke nødvendigvis handler om personens ansettelse:

offentlig klasse Ansatt {privat strengnavn; privat alder; privat int experienceInMonths; public String getName () {return name; } public int getAge () {return age; } public int getExperienceInMonths () {return experienceInMonths; }}

Det kan være lurt å trekke ut de ikke-arbeidsrelaterte eiendommene til en Person superklasse. For å trekke ut ting til en superklasse, kan vi høyreklikk hvor som helst i klassen og velg Refactor> Extract Superclass alternativet, eller bruk Alt + Shift + T. for å få frem menyen direkte:

Dette vil skape et nytt Person klasse med våre utvalgte variabler og metode, og Ansatt klassen vil bli omformet til:

offentlig klasse Ansatt utvider Person {private int experienceInMonths; public int getExperienceInMonths () {return experienceInMonths; }}

3.4. Pakke ut metode

Noen ganger kan det være lurt å trekke ut en viss kode i metoden vår til en annen metode for å holde koden ren og enkel å vedlikeholde.

La oss for eksempel si at vi har en for loop innebygd i vår metode:

public class Test {public static void main (String [] args) {for (int i = 0; i <args.length; i ++) {System.out.println (args [i]); }}}

Å påkalle Pakke ut metode veiviseren, må vi utføre følgende trinn:

  • Velg kodelinjene vi vil trekke ut
  • Høyreklikk det valgte området
  • Klikk på Refactor> Extract Method alternativ

De to siste trinnene kan også oppnås ved hurtigtaster Alt + Skift + M.. La oss se Pakke ut metode dialog:

Dette vil omformulere koden vår til:

public class Test {public static void main (String [] args) {printArgs (args); } privat statisk ugyldig printArgs (String [] args) {for (int i = 0; i <args.length; i ++) {System.out.println (args [i]); }}}

3.5. Pakk ut lokale variabler

Vi kan trekke ut visse elementer som lokale variabler for å gjøre koden vår mer lesbar.

Dette er praktisk når vi har en String bokstavelig:

public class Test {public static void main (String [] args) {System.out.println ("Number of Arguments passedlazy" src = "// www.baeldung.com/wp-content/uploads/2019/06/Eclipse- refactor-21.png ">

Det siste trinnet kan også oppnås med hurtigtasten Alt + Skift + L.. Nå kan vi trekke ut vår lokale variabel:

Og her er resultatet av denne refactoring:

public class Test {public static void main (String [] args) {final String prefix = "Number of Arguments passedextracting-konstants"> 3.6. Pakk ut konstant

Eller vi kan trekke ut uttrykk og bokstavelige verdier til statisk finale klasse attributter.

Vi kunne trekke ut 3.14 verdien til en lokal variabel, som vi nettopp så:

offentlig klasse MathUtil {offentlig dobbel omkrets (dobbel radius) {retur 2 * 3,14 * radius; }}

Men det kan være bedre å trekke det ut som en konstant, som vi trenger for:

  • Velg varen
  • Høyreklikk og velg Refactor> Ekstraher konstant

Dette åpner en dialog der vi kan gi konstanten et navn og sette synligheten, sammen med et par andre alternativer:

Nå ser koden vår litt mer lesbar ut:

offentlig klasse MathUtil {privat statisk finale dobbel PI = 3,14; offentlig dobbel omkrets (dobbel radius) {retur 2 * PI * radius; }}

4. Innfelling

Vi kan også gå den andre veien og inline kode.

Vurder a Util klasse som har en lokal variabel som bare brukes en gang:

offentlig klasse Til {public void isNumberPrime (int num) {boolean result = isPrime (num); hvis (resultat) {System.out.println ("Number is Prime"); } annet {System.out.println ("Number is Not Prime"); }} // isPrime-metode} 

Vi vil fjerne resultat lokal variabel og innebygd isPrime metodeanrop. For å gjøre dette følger vi disse trinnene:

  • Velg elementet vi vil legge inn
  • Høyreklikk og Velg Refactor> Inline alternativ

Det siste trinnet kan også oppnås ved hurtigtaster Alt + Skift + Jeg:

Etterpå har vi en variabel mindre å holde rede på:

offentlig klasse Til {public void isNumberPrime (int num) {if (isPrime (num)) {System.out.println ("Number is Prime"); } annet {System.out.println ("Number is Not Prime"); }} // isPrime-metode}

5. Trykk ned og trekk opp

Hvis vi har et foreldre-barn-forhold (som vårt forrige Ansatt og Person eksempel) mellom klassene våre, og vi vil flytte visse metoder eller variabler blant dem, kan vi bruke push / pull-alternativene som tilbys av Eclipse.

Som navnet antyder, er Presse ned alternativ flytter metoder og felt fra en overordnet klasse til alle barneklasser, mens Trekk opp flytter metoder og felt fra en bestemt barneklasse til forelder, og gjør dermed metoden tilgjengelig for alle barneklasser.

For å flytte metoder ned til barneklasser, må vi høyreklikk hvor som helst i klassen og velg Refactor> Push Down alternativ:

Dette åpner en veiviser der vi kan velge elementer som skal presses ned:

På samme måte må vi for å flytte metoder fra barneklasse til foreldreklasse høyreklikk hvor som helst i klassen og velg Refactor> Pull Up:

Dette åpner en lignende veiviser der vi kan velge elementer som skal hentes:

6. Endring av metodesignatur

For å endre metodesignaturen til en eksisterende metode, kan vi følge noen få enkle trinn:

  • Velg metoden eller plasser markøren et sted inne
  • Høyreklikk og velg Refactor> Endre metodesignatur

Det siste trinnet kan også oppnås ved hurtigtaster Alt + Skift + C.

Dette åpner en popup der du kan endre metodesignaturen tilsvarende:

7. Flytte

Noen ganger vil vi bare flytte metoder til en annen eksisterende klasse for å gjøre koden vår mer objektorientert.

Tenk på scenariet der vi har en Film klasse:

offentlig klasse Film {privat String tittel; privat dobbel pris; privat filmtype; // andre metoder}

Og Filmtype er en enkel enum:

offentlig enum MovieType {NEW, REGULAR}

Anta også at vi har et krav om at hvis en Kunde leier en film som er NY, blir det belastet to dollar mer, og at vår Kunde klasse har følgende logikk for å beregne totalkostnad():

offentlig klasse kunde {privat strengnavn; privat strengadresse; private List filmer; offentlig dobbel totalCost () {dobbelt resultat = 0; for (Filmfilm: filmer) {resultat + = movieCost (film); } returnere resultat; } privat dobbel filmKostnad (filmfilm) {if (movie.getType () .equals (MovieType.NEW)) {return 2 + movie.getPrice (); } returner movie.getPrice (); } // andre metoder}

Det er klart at beregningen av filmkostnaden er basert på Filmtype ville være mer hensiktsmessig plassert i Film klasse og ikke Kunde klasse. Vi kan enkelt flytte denne beregningslogikken i formørkelse:

  • Velg linjene du vil flytte
  • Høyreklikk og velg Refactor> Flytt alternativ

Det siste trinnet kan også oppnås ved hurtigtaster Alt + Skift + V.:

Formørkelse er smart nok til å innse at denne logikken skal være i vår Film klasse. Vi kan endre metodens navn hvis vi vil, sammen med andre avanserte alternativer.

Finalen Kunde klassekode vil bli omformet til:

offentlig klasse kunde {privat strengnavn; privat strengadresse; private List filmer; offentlig dobbel totalCost () {dobbelt resultat = 0; for (Filmfilm: filmer) {resultat + = movie.movieCost (); } returnere resultat; } // andre metoder}

Som vi kan se, er movieCost metoden er flyttet til vår Film klasse og blir brukt i refactored Kunde klasse.

8. Konklusjon

I denne opplæringen så vi på noen av de viktigste refactoringsteknikkene som tilbys av Eclipse. Vi startet med noen grunnleggende refactoring som å gi nytt navn og trekke ut. Senere så vi flyttemetoder og felt rundt forskjellige klasser.

For å lære mer kan vi alltid referere til den offisielle formørkelsesdokumentasjonen om refactoring.