Refactoring i formørkelse

1. Oversigt

På refactoring.com læser vi, at "refactoring er en disciplineret teknik til omstrukturering af en eksisterende kodekod, der ændrer dens interne struktur uden at ændre dens eksterne opførsel."

Typisk vil vi måske omdøbe variabler eller metoder, eller vi vil måske gøre vores kode mere objektorienteret ved at introducere designmønstre. Moderne IDE'er har mange indbyggede funktioner, der hjælper os med at nå disse former for refactoring-mål og mange andre.

I denne vejledning fokuserer vi på refactoring i Eclipse, en gratis populær Java IDE.

Før vi starter refactoring, anbefales det at have en solid række tests for at kontrollere, at vi ikke brækkede noget under refactoring.

2. Omdøbning

2.1. Omdøbning af variabler og metoder

Vi kan omdøbe variabler og metoder ved at følge disse enkle trin:

    • Vælg elementet
    • Højreklik på elementet
    • Klik på Refactor> Omdøb mulighed
  • Indtast det nye navn
  • Trykke Gå ind

Vi kan også udføre det andet og tredje trin efter ved hjælp af genvejstasten, Alt + Skift + R.

Når ovenstående handling udføres, finder Eclipse enhver brug af dette element i filen og erstatter dem alle på plads.

Vi kan også bruge en avanceret funktion til opdater referencen i andre klasser ved at svæve over elementet, når refaktoren er tændt og klikke på Muligheder:

Dette åbner en pop op, hvor vi både kan omdøbe variablen eller metoden og have mulighed for at opdatere referencen i andre klasser:

2.2. Omdøbning af pakker

Vi kan omdøbe en pakke ved at vælge pakkens navn og udføre de samme handlinger som i det foregående eksempel. En pop op vises straks, hvor vi kan omdøbe pakken med muligheder som opdatering af referencer og omdøbning af underpakker.

Vi kan også omdøbe pakken fra Project Explorer-visningen ved at trykke på F2:

2.3. Omdøbning af klasser og grænseflader

Vi kan omdøbe en klasse eller grænseflade ved at bruge de samme handlinger eller bare ved at trykke på F2 fra Project Explorer. Dette åbner en pop-up med muligheder for at opdatere referencer sammen med et par avancerede muligheder:

3. Uddrag

Lad os nu tale om ekstraktion. Udpakning af kode betyder tager et stykke kode og flytter det.

For eksempel kan vi udtrække kode til en anden klasse, superklasse eller grænseflade. Vi kunne endda udtrække kode til en variabel eller metode i samme klasse.

Eclipse giver en række forskellige måder at opnå ekstraktioner på, som vi vil demonstrere i de følgende afsnit.

3.1. Uddragsklasse

Antag, at vi har følgende Bil klasse i vores kodebase:

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

Antag nu, at vi vil udtrække driveroplysningerne til en anden klasse. Vi kan gøre dette ved højreklik hvor som helst i klassen og vælge Refactor> Uddragsklasse mulighed:

Dette åbner en pop op-vindue, hvor vi kan navngive klassen og vælge hvilke felter vi vil flytte sammen med få andre muligheder:

Vi kan også få vist koden før vi går videre. Når vi klikker Okay, Eclipse opretter en ny klasse med navnet Chauffør, og den forrige kode bliver ombygget til:

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

3.2. Uddrag interface

Vi kan også udtrække en grænseflade på en lignende måde. Antag, at vi har følgende Medarbejderstjeneste klasse:

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

Vi kan udtrække en grænseflade ved højreklik hvor som helst i klassen og vælge Refactor> Extract Interface mulighed, eller vi kan bruge Alt + Skift + T. genvejstastkommando for at åbne menuen direkte:

Dette åbner en pop-up, hvor vi kan indtaste grænsefladenavnet og beslutte, hvilke medlemmer der skal erklæres i grænsefladen:

Som et resultat af denne refactoring har vi en grænseflade IEmpServiceog vores Medarbejderstjeneste klasse ændres også:

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. Uddrag superklasse

Antag, at vi har en Medarbejder klasse, der indeholder flere ejendomme, der ikke nødvendigvis handler om personens ansættelse:

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

Vi vil måske udtrække de ikke-beskæftigelsesrelaterede ejendomme til en Person superklasse. For at udtrække varer til en superklasse kan vi højreklik et vilkårligt sted i klassen, og vælg Refactor> Uddrag superklasse valgmulighed, eller brug Alt + Skift + T for at åbne menuen direkte:

Dette vil skabe et nyt Person klasse med vores valgte variabler og metode, og Medarbejder klasse refaktureres til:

offentlig klasse Medarbejder udvider Person {private int experienceInMonths; public int getExperienceInMonths () {return experienceInMonths; }}

3.4. Uddragsmetode

Nogle gange vil vi måske udtrække et bestemt stykke kode inde i vores metode til en anden metode for at holde vores kode ren og nem at vedligeholde.

Lad os f.eks. Sige, at vi har en for-loop indlejret i vores metode:

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

At påberåbe sig Uddragsmetode guiden, skal vi udføre følgende trin:

  • Vælg de kodelinjer, vi vil udtrække
  • Højreklik på det valgte område
  • Klik på Refactor> Ekstraktmetode mulighed

De sidste to trin kan også opnås ved hjælp af tastaturgenvej Alt + Skift + M. Lad os se Uddragsmetode dialog:

Dette vil omformulere vores kode 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. Uddrag lokale variabler

Vi kan udtrække bestemte emner som lokale variabler for at gøre vores kode mere læsbar.

Dette er praktisk, når vi har en Snor bogstavelig:

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 sidste trin kan også opnås ved hjælp af tastaturgenvejen Alt + Skift + L.. Nu kan vi udtrække vores lokale variabel:

Og her er resultatet af denne refactoring:

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

Eller vi kan udtrække udtryk og bogstavelige værdier til statisk endelig klasse attributter.

Vi kunne udtrække 3.14 værdi til en lokal variabel, som vi lige så:

offentlig klasse MathUtil {offentlig dobbelt omkreds (dobbelt radius) {retur 2 * 3,14 * radius; }}

Men det kan være bedre at udtrække det som en konstant, som vi har brug for:

  • Vælg emnet
  • Højreklik og vælg Refactor> Udtræk konstant

Dette åbner en dialog, hvor vi kan give konstanten et navn og indstille dens synlighed sammen med et par andre muligheder:

Nu ser vores kode lidt mere læsbar ud:

offentlig klasse MathUtil {privat statisk endelig dobbelt PI = 3,14; offentlig dobbelt omkreds (dobbelt radius) {return 2 * PI * radius; }}

4. Inline

Vi kan også gå den anden vej og inline kode.

Overvej en Util klasse, der har en lokal variabel, der kun bruges en gang:

public class Util {public void isNumberPrime (int num) {boolean result = isPrime (num); hvis (resultat) {System.out.println ("Number is Prime"); } andet {System.out.println ("Nummeret er ikke prime"); }} // isPrime-metode} 

Vi ønsker at fjerne resultat lokal variabel og inline isPrime metodeopkald. For at gøre dette følger vi disse trin:

  • Vælg det emne, vi vil integrere
  • Højreklik og Vælg Refactor> Inline mulighed

Det sidste trin kan også opnås ved tastaturgenvej Alt + Skift + I:

Bagefter har vi en variabel mindre at holde styr på:

offentlig klasse indtil {public void isNumberPrime (int num) {if (isPrime (num)) {System.out.println ("Number is Prime"); } andet {System.out.println ("Nummeret er ikke prime"); }} // isPrime-metode}

5. Skub ned og træk op

Hvis vi har et forhold mellem forældre og barn (som vores tidligere Medarbejder og Person eksempel) mellem vores klasser, og vi vil flytte visse metoder eller variabler blandt dem, kan vi bruge de push / pull-muligheder, der leveres af Eclipse.

Som navnet antyder, er Tryk ned option flytter metoder og felter fra en overordnet klasse til alle underordnede klasser, mens Træk op flytter metoder og felter fra en bestemt barneklasse til forælder og gør metoden således tilgængelig for alle barneklasser.

For at flytte metoder ned til børneklasser er vi nødt til det højreklik et vilkårligt sted i klassen, og vælg Refactor> Skub ned mulighed:

Dette åbner en guide, hvor vi kan vælge emner, der skal skubbes ned:

På samme måde er det nødvendigt for at flytte metoder fra en barneklasse til forældreklassen højreklik et vilkårligt sted i klassen, og vælg Refactor> Træk op:

Dette åbner en lignende guide, hvor vi kan vælge emner, der skal trækkes op:

6. Ændring af en metodesignatur

For at ændre metodesignaturen for en eksisterende metode kan vi følge et par enkle trin:

  • Vælg metoden, eller placer markøren et eller andet sted indeni
  • Højreklik og vælg Refactor> Skift metodesignatur

Det sidste trin kan også opnås ved tastaturgenvej Alt + Skift + C.

Dette åbner en popup, hvor du kan ændre metodesignaturen i overensstemmelse hermed:

7. Flytter

Nogle gange vil vi bare flytte metoder til en anden eksisterende klasse for at gøre vores kode mere objektorienteret.

Overvej scenariet, hvor vi har en Film klasse:

offentlig klassefilm {privat strengetitel; privat dobbelt pris; privat filmtype type; // andre metoder}

Og Filmtype er en simpel enum:

offentlig enum MovieType {NEW, REGULAR}

Antag også, at vi har et krav om, at hvis en Kunde lejer en film der er NY, vil det blive opkrævet to dollars mere, og at vores Kunde klasse har følgende logik til at beregne Udgifter i alt():

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

Det er klart, at beregningen af ​​filmomkostningerne er baseret på Filmtype ville være mere hensigtsmæssigt placeret i Film klasse og ikke Kunde klasse. Vi kan let flytte denne beregningslogik i formørkelse:

  • Vælg de linjer, du vil flytte
  • Højreklik og vælg Refactor> Flyt mulighed

Det sidste trin kan også opnås ved tastaturgenvej Alt + Skift + V.:

Formørkelse er smart nok til at indse, at denne logik skal være i vores Film klasse. Vi kan ændre metodens navn, hvis vi ønsker det sammen med andre avancerede muligheder.

Finalen Kunde klassekode vil blive omformuleret til:

offentlig klasse kunde {privat strengnavn; privat strengadresse; private listefilm; offentlig dobbelt totalCost () {dobbelt resultat = 0; til (Filmfilm: film) {resultat + = film.movieCost (); } returnere resultat } // andre metoder}

Som vi kan se, er movieCost metoden er flyttet til vores Film klasse og bruges i refactored Kunde klasse.

8. Konklusion

I denne vejledning undersøgte vi nogle af de vigtigste refactoringsteknikker leveret af Eclipse. Vi startede med nogle grundlæggende refactoring som omdøbning og udpakning. Senere så vi flytningsmetoder og felter omkring forskellige klasser.

For at lære mere kan vi altid henvise til den officielle formørkelsesdokumentation om refactoring.