ConstructiCat Logo
CodeBust.
Browse section ▾

Séparer la requête du modificateur.

Problem

Avez-vous une méthode qui renvoie une valeur mais modifie aussi quelque chose à l'intérieur d'un objet ?

Solution

Scindez la méthode en deux méthodes distinctes. Comme on peut s'y attendre, l'une doit renvoyer la valeur et l'autre modifier l'objet.

##Example

Avant
Customer getTotalOutstandingAndSetReadyForSummaries()
Après
Customer getTotalOutstanding()setReadyForSummaries()

##Why Refactor

Cette technique de factorisation met en œuvre la séparation des responsabilités entre commande et requête (Command and Query Responsibility Segregation). Ce principe nous dit de séparer le code chargé de récupérer des données du code qui modifie quelque chose à l'intérieur d'un objet.

Le code servant à récupérer des données est appelé une requête. Le code servant à modifier des éléments de l'état visible d'un objet est appelé un modificateur. Lorsqu'une requête et un modificateur sont combinés, vous n'avez aucun moyen d'obtenir des données sans en modifier la condition. Autrement dit, vous posez une question et pouvez en changer la réponse au moment même où vous la recevez. Ce problème devient encore plus grave lorsque la personne qui appelle la requête peut ignorer les « effets de bord » de la méthode, ce qui conduit souvent à des erreurs à l'exécution.

Mais souvenez-vous que les effets de bord ne sont dangereux que dans le cas de modificateurs qui changent l'état visible d'un objet. Il peut s'agir, par exemple, de champs accessibles depuis l'interface publique d'un objet, d'une entrée dans une base de données, dans des fichiers, etc. Si un modificateur ne fait que mettre en cache une opération complexe et l'enregistrer dans un champ privé d'une classe, il ne peut guère provoquer d'effets de bord.

##Benefits

  • Si vous disposez d'une requête qui ne modifie pas l'état de votre programme, vous pouvez l'appeler autant de fois que vous le souhaitez sans avoir à craindre des changements involontaires du résultat causés par le simple fait d'appeler la méthode.

##How to Refactor

  1. Créez une nouvelle méthode de requête pour renvoyer ce que faisait la méthode d'origine.

  2. Modifiez la méthode d'origine pour qu'elle ne renvoie que le résultat de l'appel à la nouvelle méthode de requête.

  3. Remplacez toutes les références à la méthode d'origine par un appel à la méthode de requête. Juste avant cette ligne, placez un appel à la méthode de modification. Cela vous évitera des effets de bord au cas où la méthode d'origine était utilisée dans la condition d'un opérateur conditionnel ou d'une boucle.

  4. Débarrassez-vous du code qui renvoie une valeur dans la méthode d'origine, qui est désormais devenue une véritable méthode de modification.