Remplacer un code type par des sous-classes.
Vous avez un type codé qui affecte directement le comportement du programme (les valeurs de ce champ déclenchent différents codes dans des conditions).
Créez des sous-classes pour chaque valeur du type codé. Puis extrayez les comportements pertinents de la classe d'origine vers ces sous-classes. Remplacez le code de contrôle de flux par du polymorphisme.
##Example
##Why Refactor
Cette technique de refactoring est une variante plus compliquée de Remplacer un code type par une classe.
Comme dans la première méthode de refactoring, vous avez un ensemble de valeurs simples qui constituent toutes les valeurs autorisées pour un champ. Bien que ces valeurs soient souvent spécifiées sous forme de constantes et portent des noms compréhensibles, leur utilisation rend votre code très sujet aux erreurs car elles restent en réalité des primitives. Par exemple, vous avez une méthode qui accepte l'une de ces valeurs dans ses paramètres. À un certain moment, au lieu de la constante USER_TYPE_ADMIN avec la valeur "ADMIN", la méthode reçoit la même chaîne en minuscules ("admin"), ce qui provoquera l'exécution d'autre chose que ce que l'auteur (vous) avait prévu.
Ici, nous avons affaire à du code de contrôle de flux tel que les conditions if, switch et ?:. Autrement dit, des champs à valeurs codées (comme $user->type === self::USER_TYPE_ADMIN) sont utilisés à l'intérieur des conditions de ces opérateurs. Si nous devions utiliser Remplacer un code type par une classe ici, toutes ces constructions de contrôle de flux seraient au mieux déplacées vers une classe responsable du type de données. Au final, cela créerait bien sûr une classe de type très similaire à l'originale, avec les mêmes problèmes.
##Benefits
-
Supprimez le code de contrôle de flux. Au lieu d'un
switchvolumineux dans la classe d'origine, déplacez le code vers les sous-classes appropriées. Cela améliore le respect du Principe de responsabilité unique et rend le programme plus lisible en général. -
Si vous devez ajouter une nouvelle valeur pour un type codé, il vous suffit d'ajouter une nouvelle sous-classe sans toucher au code existant (cf. le Principe ouvert/fermé).
-
En remplaçant le code type par des classes, nous ouvrons la voie au typage des méthodes et des champs au niveau du langage de programmation. Cela ne serait pas possible avec de simples valeurs numériques ou chaînes contenues dans un type codé.
##How to Refactor
-
Utilisez Auto-encapsuler un champ pour créer un getter pour le champ qui contient le code type.
-
Rendez le constructeur de la superclasse privé. Créez une méthode de fabrique statique avec les mêmes paramètres que le constructeur de la superclasse. Elle doit contenir le paramètre qui prendra les valeurs initiales du type codé. Selon ce paramètre, la méthode de fabrique créera des objets de différentes sous-classes. Pour ce faire, vous devez y créer une grande condition mais, au moins, ce sera la seule lorsqu'elle est vraiment nécessaire ; sinon, les sous-classes et le polymorphisme s'en chargeront.
-
Créez une sous-classe unique pour chaque valeur du type codé. Dans celle-ci, redéfinissez le getter du type codé afin qu'il retourne la valeur correspondante du type codé.
-
Supprimez le champ contenant le code type de la superclasse. Rendez son getter abstrait.
-
Maintenant que vous avez des sous-classes, vous pouvez commencer à déplacer les champs et les méthodes de la superclasse vers les sous-classes correspondantes (à l'aide de Descendre un champ et Descendre une méthode).
-
Lorsque tout ce qui peut l'être a été déplacé, utilisez Remplacer une condition par du polymorphisme afin d'éliminer une bonne fois pour toutes les conditions qui utilisent le code type.