Eclipse a diverses fonctions de refactoring, mais pour être honnête, je n'ai pas vraiment compris ce qui se passerait si je les exécutais, alors je les ai résumées.
Le refactoring est le processus d'amélioration de la structure interne tout en préservant le comportement externe du logiciel.
Il n'y a pas de design parfait. À proprement parler, même si cela semble parfait au moment de la conception, il ne le sera pas avec le temps. De plus, personne ne sait quel type de requêtes sortira à l'avenir et qui ajoutera des fonctions où.
Un exemple où le design n'est pas parfait
«Je ne pensais qu'aux espèces et aux cartes de crédit comme moyens de paiement, mais il est maintenant nécessaire de prendre en charge d'autres paiements sans espèces. ――Le délai de livraison étant court, nous avons pris des mesures ad hoc pour limiter la portée d'influence.
Comme la conception se détériore avec le temps, il est nécessaire d'effectuer un entretien régulier.
Un code bien organisé est hautement lisible et peut réduire le temps nécessaire aux développeurs pour lire le code. De plus, cela facilite la recherche de bogues.
Si la conception n'est pas bonne, la dette technique sera accumulée et le même changement sera appliqué à de nombreux endroits. En continuant à refactoriser, la dette est éliminée, et même si le nombre de fonctions augmente, l'effort de développement peut être réduit.
Malheureusement, la refactorisation n'est pas une solution miracle.
Si vous n'apportez aucune modification à votre code existant, la refactorisation aura peu d'effet, ne laissant que les risques. Il n'y a pas de rationalité économique là-bas, c'est juste l'auto-satisfaction.
Si vous développez une API et que vous ne savez pas qui l'utilise, vous ne pouvez pas la modifier.
De par sa nature même, le refactoring n'augmente pas la fonctionnalité du système. Si votre patron ne comprend pas l'importance de la refactorisation, faites de votre mieux pour le convaincre. Si vous ne pouvez pas vous convaincre, abandonnez gracieusement pour ne pas être tenu responsable. ~~ (Et dans les coulisses, refactorisons silencieusement en tant que professionnel du logiciel.) ~~ Cela peut être évité lorsque les délais de livraison sont serrés ou lorsque toutes les modifications doivent être testées manuellement.
La refactorisation peut aller de petits changements tels que le changement de nom des variables locales à des changements majeurs tels que le remplacement de l'instruction switch par un polymorphisme dans la classe. Si le code à refactoriser est protégé par des tests, vous pouvez le refactoriser en toute confiance, mais le code hérité n'a pas de tests, vous ne pouvez donc pas refactoriser en toute confiance. Cependant, en ce qui concerne les outils de refactoring fournis dans des environnements de développement intégrés tels qu'Eclipse, ils ont été exécutés (testés) des milliers de fois dans le monde, de sorte que le refactoring peut être effectué de manière relativement sûre, même dans un environnement sans test automatique. Je vais. ⚠️ Pas sûr à 100%.
Version: 2019-06 (4.12.0) Build id: 20190614-1200
Sélectionnez la pièce que vous souhaitez refactoriser et cliquez avec le bouton droit de la souris → Vous pouvez l'exécuter à partir du menu de refactorisation.
Dans le cas d'un raccourci, c'est ʻAlt+
Ctrl +
T. (Pour Mac, ʻAlt
+ ⌘
+ T
)
Le refactoring peut affecter plusieurs classes et ne peut pas être retourné avec ctrl + z
après plusieurs exécutions.
Effectuez des sauvegardes fréquentes afin de pouvoir annuler vos modifications.
Le refactoring IDE est fondamentalement sûr, mais exécutez des tests automatisés aussi souvent que possible pour vous assurer que le refactoring n'a pas changé votre comportement.
Java a un mécanisme puissant appelé réflexion, mais il ne bénéficie pas de la vérification du type de compilateur. Même l'outil de refactoring de l'EDI ne sera pas applicable, donc si vous l'utilisez dans votre code, vous ne pourrez pas détecter que vous avez cassé le code jusqu'à ce que vous l'exécutiez. Si vous l'utilisez dans le programme, examinez en profondeur la plage d'influence. Si vous développez un framework ou un plug-in, vous utilisez peut-être la réflexion. ~~ L'utilisez-vous pour interrompre les modificateurs d'accès dans votre code de test? Qui a fait cela? ~~
Enfin le sujet principal. Sur la base de mon propre jugement et de mes préjugés, j'ai organisé les éléments que j'utilise le plus souvent et les éléments que je pense pouvoir utiliser.
** Applicable **
Paquets, classes, méthodes, variables
efficacité
Renommer.
Vous pouvez changer les noms de variables, les noms de méthodes et les noms de classes, tels que "Pourquoi avez-vous utilisé cette abréviation?" Ou ʻa ou ʻinstanse2
, ou la dénomination négligée, en noms significatifs.
** Facultatif (lorsqu'il est appliqué à la méthode) **
Conserver la méthode d'origine en tant que délégation à la méthode renommée + marquer comme obsolète
Il est également possible de changer la méthode ouverte sur l'extérieur tout en conservant la méthode d'origine pour maintenir la compatibilité.
Si vous sélectionnez la marque comme obsolète, «@ deprecated» sera ajouté.
before
String getCpyNm() {
return cpyNm;
}
after
String getCompanyName() {
return companyName;
}
after+option
/**
* @deprecated {@link #getCompanyName()}Substitut
*/
public String getCpyNm() {
return getCompanyName();
}
public String getCompanyName() {
return companyName;
}
** Facultatif (si appliqué à la classe) **
Les options suivantes sont disponibles.
--Mises à jour des variables et des méthodes avec des noms similaires
Il n'est pas sûr de changer le commentaire ou le nom de méthode similaire au lieu de la partie référencée, il est donc essentiel de le vérifier dans l'aperçu.
** Applicable ** Ligne sélectionnée dans la méthode efficacité Séparez la pièce sélectionnée comme une méthode distincte. S'il y a des doublons dans le code, il est possible de remplacer plusieurs doublons à la fois.
before
public void printAverage(int a, int b, int c) {
int sum = a + b+c;
int average = sum/3;
System.out.println(average);
}
after
public void printAverage(int a, int b, int c) {
int average = getAverage(a, b, c);
System.out.println(average);
}
private int getAverage(int a, int b, int c) {
int sum = a + b+c;
int average = sum/3;
return average;
}
** Applicable ** Formule sélectionnée ou formule conditionnelle dans la méthode efficacité Divisez de longues expressions, etc., ou introduisez des variables explicatives Inverse de en ligne
before
public int getTotal(int price) {
int result = (int) (price * 0.8 * 1.10);
return result;
}
after
public int getTotal(int price) {
double discountPrice = price * 0.8;
int result = (int) (discountPrice * 1.10);
return result;
}
** Applicable ** variable efficacité Remplacer les déclarations de variables redondantes par leurs valeurs Inverse de l'extraction de variables locales
before
public int getTotal(int price) {
double discountPrice = price * 0.8;
int result = (int) (discountPrice * 1.10);
return result;
}
after
public int getTotal(int price) {
int result = (int) ((price * 0.8) * 1.10);
return result;
}
** Applicable ** constant efficacité Remplacez la constante par une variable membre. Seules les valeurs statiques peuvent être utilisées.
before
public int getTotal(int price) {
int result = (int) (price * 0.8 * 1.10);
return result;
}
after
public static final double TAX_RATE = 1.10;
public int getTotal(int price) {
int result = (int) (price * 0.8 * TAX_RATE);
return result;
}
** Applicable ** Variables de membre efficacité Générez une variable membre getter / setter et remplacez la méthode de référence par une qui utilise getter / setter. option Si vous définissez «accès au champ en type déclaratif» sur «contenir la référence de champ», vous pouvez conserver la valeur du champ directement référencée.
before
public class Refactoring {
private String companyName = "";
private int companyId = 0;
public Refactoring(String companyName, int companyId) {
this.companyName = companyName;
this.companyId = companyId;
}
}
after
public class Refactoring {
private String companyName = "";
private int companyId = 0;
public Refactoring(String companyName, int companyId) {
this.companyName = companyName;
this.setCompanyId(companyId);
}
/**
* @return companyId
*/
private int getCompanyId() {
return companyId;
}
/**
* @param companyId set companyId
*/
private void setCompanyId(int companyId) {
this.companyId = companyId;
}
}
** Applicable ** Variables locales efficacité Remplacez les variables locales par des variables membres. Similaire à l'extraction constante option Les modificateurs d'accès aux champs et les positions d'initialisation peuvent être modifiés
before
public class Refactoring {
public int getTotal(int price) {
double discountRate = 0.8;
int result = (int) (price * discountRate * 1.10);
return result;
}
}
after
public class Refactoring {
private double discountRate = 0.8;
public int getTotal(int price) {
int result = (int) (price * discountRate * 1.10);
return result;
}
}
** Applicable ** Paquet, classe efficacité Déplacer une classe vers un autre package, déplacer / renommer un package. Si vous déplacez un package, vous pouvez modifier les sous-packages à la fois.
package com.example.refactoring;
package com.example.refactoring.util;
** Applicable ** variable statique, méthode statique efficacité Vous pouvez déplacer des variables statiques et des méthodes statiques vers une autre classe. Il peut également être utilisé pour les variables membres, mais comme il ne peut pas contenir de référence, il y a une forte probabilité qu'une erreur de compilation se produise. .. .. (S'agit-il de refactoring?)
before
public class Refactoring {
public static final String staticString = "s";
public static String getStaticString() {
return staticString;
}
}
public class OtherClass {
}
after
public class Refactoring {
public static String getStaticString() {
return OtherClass.staticString;
}
}
public class OtherClass {
public static final String staticString = "s";
}
** Applicable ** Méthode efficacité Ajouter, supprimer ou modifier des arguments de méthode Un tri problématique est également possible avec copie option Si vous cochez «Conserver la méthode d'origine comme délégation à la méthode modifiée», vous pouvez conserver la méthode de signature d'origine.
before
public Refactoring(String companyName) {
this.companyName = companyName;
}
after
public Refactoring(String companyName, String newParam) {
this.companyName = companyName;
}
after(Conserver la méthode d'origine en tant que délégation à la méthode modifiée)
/**
* @deprecated {@link #Refactoring(String,String)}Substitut
*/
public Refactoring(String companyName) {
this(companyName, null);
}
public Refactoring(String companyName, String newParam) {
this.companyName = companyName;
}
** Applicable **
classe
efficacité
Créez une interface à partir d'une classe existante.
Vous pouvez créer une interface en sélectionnant n'importe quelle méthode publique d'une classe existante, l'interface créée est automatiquement spécifiée dans ʻimplements, et la méthode est annotée avec
@ Override`.
before
public class Refactoring {
private String companyName = "";
public String getCompanyName() {
return companyName;
}
}
after
public interface RefactoringInterface {
String getCompanyName();
}
public class Refactoring implements RefactoringInterface {
private String companyName = "";
@Override
public String getCompanyName() {
return companyName;
}
}
** Applicable ** Classe (variable de membre substantielle) efficacité Regroupez les variables de membre dans des classes distinctes. Il est utilisé lorsque la classe devient gonflée ou lorsque des éléments connexes tels que l'adresse IP et le numéro de port sont réunis. Les méthodes ne peuvent pas être extraites en utilisant uniquement des variables membres. option La destination d'extraction peut être sélectionnée à partir de la classe de premier niveau et de la classe anonyme. Dans le cas de la classe de niveau supérieur, elle est extraite comme une autre classe et Dans le cas d'une classe anonyme, les classes sont extraites dans la même classe.
before
public class Refactoring {
private String companyName = "";
private String postNo = "";
public void main() {}
}
after(Pour une classe de haut niveau)
public class Refactoring {
private RefactoringData data = new RefactoringData("", "");
public void main() {}
}
public class RefactoringData {
public String companyName;
public String postNo;
public RefactoringData(String companyName, String postNo) {
this.companyName = companyName;
this.postNo = postNo;
}
}
after(Pour les cours anonymes)
public class Refactoring {
public static class RefactoringData {
public String companyName;
public String postNo;
public RefactoringData(String companyName, String postNo) {
this.companyName = companyName;
this.postNo = postNo;
}
}
private RefactoringData data = new RefactoringData("", "");
public void main() {}
}
** Applicable ** Méthode efficacité Combinez des arguments arbitraires en un seul objet option Si vous cochez «Conserver la méthode d'origine comme délégation à la méthode modifiée», vous pouvez conserver la méthode de signature d'origine. Vous pouvez sélectionner l'objet paramètre à générer à partir de la «classe de premier niveau» ou de la «classe anonyme».
before
public class Refactoring {
public Refactoring(String companyName, int companyId) {
this.companyName = companyName;
this.companyId = companyId;
}
}
after(Spécifier la classe de niveau supérieur)
public class Refactoring {
public Refactoring(RefactoringParameter parameterObject) {
this.companyName = parameterObject.companyName;
this.companyId = parameterObject.companyId;
}
}
public class RefactoringParameter {
public String companyName;
public int companyId;
public RefactoringParameter(String companyName, int companyId) {
this.companyName = companyName;
this.companyId = companyId;
}
}
after(Spécifiez la classe anonyme)
public class Refactoring {
/**
* @deprecated {@link #Refactoring(RefactoringParameter)}Substitut
*/
public Refactoring(String companyName, int companyId) {
this(new RefactoringParameter(companyName, companyId));
}
public Refactoring(RefactoringParameter parameterObject) {
this.companyName = parameterObject.companyName;
this.companyId = parameterObject.companyId;
}
}
public class RefactoringParameter {
//L'objet de paramètre est le même
}
** Applicable ** Variables et constantes dans la méthode efficacité Changer les variables et les constantes d'une méthode en arguments de méthode
before
public String getCompanyName() {
return "prefix_" + companyName;
}
after
public String getCompanyName(String prefix) {
return prefix + companyName;
}
** Applicable ** classe efficacité Créez une super classe à partir d'une classe existante. Une super classe peut être créée en spécifiant des variables membres et des méthodes arbitraires à partir d'une classe existante, et ʻextends` est automatiquement spécifié.
before
public class Refactoring {
private String companyName = "";
public String getCompanyName() {
return companyName;
}
}
after
public class RefactoringSuper {
private String companyName = "";
public String getCompanyName() {
return companyName;
}
}
public class Refactoring extends RefactoringSuper {
}
** Applicable ** Variables et méthodes des membres de la superclasse / sous-classe efficacité Déplacer les variables membres et les méthodes entre les superclasses / sous-classes Le pull-up passe de la sous-classe à la superclasse, Le refoulement passe de la super classe à la sous-classe. ** Facultatif (pendant le pushdown) ** Si vous sélectionnez «Laisser la déclaration abstraite», vous pouvez laisser la méthode déplacée vers la super classe en tant qu'abstruct.
Après le pull-up
public class SuperClass {
private String companyName = "";
public String getCompanyName() {
return companyName;
}
}
public class Refactoring extends SuperClass {
}
Après le refoulement
public class SuperClass {
}
public class Refactoring extends SuperClass {
private String companyName = "";
public String getCompanyName() {
return companyName;
}
}
Après le refoulement+Laisser une déclaration abstraite
public abstract class SuperClass {
public abstract String getCompanyName();
}
public class Refactoring extends SuperClass {
private String companyName = "";
public String getCompanyName() {
return companyName;
}
}
** Applicable ** constructeur efficacité Remplacez le constructeur par une méthode de fabrique statique. Il est utilisé lorsque vous souhaitez faire de la classe cible une classe singleton ou lorsque vous souhaitez modifier de manière flexible la méthode de génération.
before
public class Refactoring {
private String companyName = "";
public Refactoring(String companyName) {
this.companyName = companyName;
}
}
after
public class Refactoring {
public static Refactoring createRefactoring(String companyName) {
return new Refactoring(companyName);
}
private String companyName = "";
private Refactoring(String companyName) {
this.companyName = companyName;
}
}
** Applicable ** Classe (référence dans pratiquement d'autres méthodes) efficacité Si une super classe peut être utilisée comme substitut, remplacez-la par une super classe. Dans l'exemple ci-dessous, la déclaration de la classe Use a été remplacée, mais c'est la sous-classe qui effectue le refactoring.
Définition de classe
public class SuperClass {
protected String companyName = "";
public String getCompanyName() {
return companyName;
}
}
public class Refactoring extends SuperClass {
}
before
public class Use {
public void main() {
Refactoring instance = new Refactoring("", 0);
System.out.println(instance.getCompanyName());
}
}
after
public class Use {
public void main() {
SuperClass instance = new Refactoring("", 0);
System.out.println(instance.getCompanyName());
}
}
** Applicable ** Classe anonyme (classe interne) efficacité Déplacer la classe anonyme vers un autre fichier
before
public class Refactoring {
private String companyName = "";
private int companyId = 0;
public static class RefactoringParameter {
public String companyName;
public int companyId;
public RefactoringParameter(String companyName, int companyId) {
this.companyName = companyName;
this.companyId = companyId;
}
}
public Refactoring(RefactoringParameter parameterObject) {
this.companyName = parameterObject.companyName;
this.companyId = parameterObject.companyId;
}
}
after
public class Refactoring {
private String companyName = "";
private int companyId = 0;
public Refactoring(RefactoringParameter parameterObject) {
this.companyName = parameterObject.companyName;
this.companyId = parameterObject.companyId;
}
}
public class RefactoringParameter {
public String companyName;
public int companyId;
public RefactoringParameter(String companyName, int companyId) {
this.companyName = companyName;
this.companyId = companyId;
}
}
** Applicable ** Type de variable membre, type de retour de méthode, type de variable efficacité Remplacez le type par un type de superclasse. Il peut être changé en une super classe comme le type String → Type d'objet. Cependant, il ne peut pas être modifié s'il est référencé en tant que type String dans une autre classe et n'est pas compatible.
before
public String getCompanyName() {
return companyName;
}
after
public Object getCompanyName() {
return companyName;
}
J'ai appris beaucoup de fonctionnalités sur le refactoring d'Eclipse pour la première fois. Le nombre de: star: est petit pour ceux que je ne savais pas personnellement utiliser. S'il vous plaît laissez-moi savoir s'il y a une utilisation pratique. Ce n'est pas sûr à 100%, mais c'est extrêmement plus rapide et plus sûr que la méthode de réparation manuelle de la pièce où l'erreur s'est produite après l'avoir modifiée, alors refactorisons-la régulièrement.