Logo ConstructiCat
CodeBust.
Parcourir la section ▾

Remplacer une sous-classe par des champs.

Problème

Vous avez des sous-classes qui ne diffèrent que par leurs méthodes (renvoyant des constantes).

Solution

Remplacez ces méthodes par des champs dans la classe parente et supprimez les sous-classes.

##Exemple

Avant
abstract class Person {
  abstract boolean isMale();
  abstract char getCode();
}
class Male extends Person {
  boolean isMale() { return true; }
  char getCode() { return 'M'; }
}
class Female extends Person {
  boolean isMale() { return false; }
  char getCode() { return 'F'; }
}
Après
class Person {
  private final boolean male;
  private final char code;

  private Person(boolean male, char code) {
    this.male = male;
    this.code = code;
  }
  static Person createMale() { return new Person(true, 'M'); }
  static Person createFemale() { return new Person(false, 'F'); }
  boolean isMale() { return male; }
  char getCode() { return code; }
}

##Pourquoi refactoriser

Parfois, la refactorisation est exactement ce qu'il faut pour éviter le code de type (type code).

Dans un cas de ce genre, une hiérarchie de sous-classes peut ne différer que par les valeurs renvoyées par certaines méthodes. Ces méthodes ne sont même pas le résultat d'un calcul : elles sont strictement définies dans les méthodes elles-mêmes ou dans les champs qu'elles renvoient. Pour simplifier l'architecture des classes, cette hiérarchie peut être condensée en une seule classe contenant un ou plusieurs champs portant les valeurs nécessaires, selon la situation.

Ces modifications peuvent devenir nécessaires après avoir déplacé une grande partie des fonctionnalités d'une hiérarchie de classes vers un autre endroit. La hiérarchie actuelle n'a plus grande valeur et ses sous-classes ne sont désormais qu'un poids mort.

##Avantages

  • Simplifie l'architecture du système. Créer des sous-classes est excessif si tout ce que vous voulez, c'est renvoyer des valeurs différentes dans des méthodes différentes.

##Comment refactoriser

  1. Appliquez Remplacer un constructeur par une méthode de fabrique aux sous-classes.

  2. Remplacez les appels aux constructeurs des sous-classes par des appels à la méthode de fabrique de la superclasse.

  3. Dans la superclasse, déclarez des champs pour stocker les valeurs de chacune des méthodes des sous-classes qui renvoient des valeurs constantes.

  4. Créez un constructeur protégé dans la superclasse pour initialiser les nouveaux champs.

  5. Créez ou modifiez les constructeurs existants des sous-classes pour qu'ils appellent le nouveau constructeur de la classe parente en lui transmettant les valeurs appropriées.

  6. Implémentez chaque méthode constante dans la classe parente pour qu'elle renvoie la valeur du champ correspondant. Supprimez ensuite la méthode de la sous-classe.

  7. Si le constructeur de la sous-classe comporte des fonctionnalités supplémentaires, utilisez Mettre une méthode en ligne pour intégrer le constructeur dans la méthode de fabrique de la superclasse.

  8. Supprimez la sous-classe.