---
title: "Remplacer un code type par des sous-classes"
type: "refactoring-technique"
slug: "replace-type-code-with-subclasses"
url: "http://localhost:3000/fr/replace-type-code-with-subclasses.md"
category: "Organizing Data"
description: "Problème : 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). Solution : 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."
---
# Remplacer un code type par des sous-classes

> Problème : 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). Solution : 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.

## Problem

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).

## Solution

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.

## Why Refactor

Cette technique de refactoring est une variante plus compliquée de [Remplacer un code type par une classe](/fr/replace-type-code-with-class).

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](/fr/replace-type-code-with-class) 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 `switch` volumineux 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

1. Utilisez [Auto-encapsuler un champ](/fr/self-encapsulate-field) pour créer un getter pour le champ qui contient le code type.
2. 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.
3. 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é.
4. Supprimez le champ contenant le code type de la superclasse. Rendez son getter abstrait.
5. 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](/fr/push-down-field) et [Descendre une méthode](/fr/push-down-method)).
6. Lorsque tout ce qui peut l'être a été déplacé, utilisez [Remplacer une condition par du polymorphisme](/fr/replace-conditional-with-polymorphism) afin d'éliminer une bonne fois pour toutes les conditions qui utilisent le code type.
## Relations

**Similar techniques**

- [Remplacer un code de type par une classe](/fr/replace-type-code-with-class.md)
- [Remplacer le code de type par State/Strategy](/fr/replace-type-code-with-state-strategy.md)

**Opposite refactorings**

- [Remplacer une sous-classe par des champs](/fr/replace-subclass-with-fields.md)

**Eliminates smells**

- [Obsession des types primitifs](/fr/smells/primitive-obsession.md)

