Séparation commande-requête - Command–query separation

La séparation commande-requête ( CQS ) est un principe de programmation informatique impérative . Il a été conçu par Bertrand Meyer dans le cadre de ses travaux pionniers sur le langage de programmation Eiffel .

Il indique que chaque méthode doit être soit une commande qui exécute une action, soit une requête qui renvoie des données à l'appelant, mais pas les deux. En d'autres termes, poser une question ne doit pas changer la réponse . Plus formellement, les méthodes ne doivent renvoyer une valeur que si elles sont référentiellement transparentes et ne possèdent donc pas d' effets secondaires .

Lien avec la conception par contrat

La séparation commande-requête est particulièrement bien adaptée à une méthodologie de conception par contrat (DbC), dans laquelle la conception d'un programme est exprimée sous forme d' assertions intégrées dans le code source , décrivant l' état du programme à certains moments critiques. Dans DbC, les assertions sont considérées comme des annotations de conception - et non comme une logique de programme - et en tant que telles, leur exécution ne doit pas affecter l'état du programme. CQS est bénéfique pour DbC car toute méthode de retour de valeur (toute requête) peut être appelée par n'importe quelle assertion sans craindre de modifier l'état du programme.

En termes théoriques, cela établit une mesure de la raison, par laquelle on peut raisonner sur l'état d'un programme sans modifier simultanément cet état. Concrètement, CQS permet de contourner toutes les vérifications d'assertion dans un système fonctionnel pour améliorer ses performances sans modifier par inadvertance son comportement. CQS peut également empêcher l'apparition de certains types d' insectes heisen .

Impact plus large sur le génie logiciel

Même au-delà du lien avec la conception par contrat, CQS est considéré par ses adhérents comme ayant un effet simplificateur sur un programme, rendant ses états (via des requêtes) et ses changements d'état (via des commandes) plus compréhensibles.

CQS est bien adapté à la méthodologie orientée objet , mais peut également être appliqué en dehors de la programmation orientée objet. Étant donné que la séparation des effets secondaires et des valeurs de retour n'est pas intrinsèquement orientée objet, CQS peut être appliqué avec profit à tout paradigme de programmation qui nécessite un raisonnement sur les effets secondaires.

Séparation des responsabilités des requêtes de commande

La séparation des responsabilités des requêtes de commande ( CQRS ) applique le principe CQS en utilisant des objets Query et Command séparés pour récupérer et modifier les données, respectivement.

Autres modèles architecturaux

  • À mesure que nous nous éloignons d'une représentation unique avec laquelle nous interagissons via CRUD, nous pouvons facilement passer à une interface utilisateur basée sur les tâches.
  • CQRS s'adapte bien aux modèles de programmation basés sur les événements. Il est courant de voir un système CQRS divisé en services distincts communiquant avec Event Collaboration. Cela permet à ces services de tirer facilement parti de l' architecture événementielle .
  • Le fait d'avoir des modèles distincts soulève des questions sur la difficulté de maintenir ces modèles cohérents, ce qui augmente la probabilité d'utiliser une cohérence éventuelle.
  • Pour de nombreux domaines, une grande partie de la logique requise est nécessaire lors de la mise à jour, il peut donc être judicieux d'utiliser Eager Read Derivation pour simplifier vos modèles côté requête.
  • Si le modèle d'écriture génère des événements pour toutes les mises à jour, vous pouvez structurer les modèles de lecture en tant qu'affiches d'événements, leur permettant d'être des images mémoire et évitant ainsi de nombreuses interactions avec la base de données.
  • CQRS est adapté aux domaines complexes, ceux qui bénéficient également du Domain-Driven Design .

Limites

CQS peut introduire des complexités pour la mise en œuvre correcte des logiciels réentrants et multithreads . Cela se produit généralement lorsqu'un modèle non thread-safe est utilisé pour implémenter la séparation commande-requête.

Voici un exemple simple qui ne suit pas CQS, mais qui est utile pour les logiciels multi-threads car il résout la complexité du verrouillage pour toutes les autres parties du programme, mais ce faisant, il ne suit pas CQS car la fonction mute à la fois l'état et le renvoie :

private int x;
public int incrementAndReturnX() {
    lock x;   // by some mechanism
    x = x + 1;
    int x_copy = x;
    unlock x; // by some mechanism
    return x_copy;
}

Voici une version conforme au CQS. Notez qu'il n'est utilisable en toute sécurité que dans les applications à thread unique. Dans un programme multithread, il existe une condition de concurrence dans l'appelant, entre où increment()et value()serait appelé :

private int x;
public int value() {
    return x;
}
void increment() {
    x = x + 1;
}

Même dans les programmes à thread unique, il est parfois sans doute beaucoup plus pratique d'avoir une méthode qui est une requête et une commande combinées. Martin Fowler cite la pop()méthode d'une pile comme exemple.

Voir également

Les références

Lectures complémentaires

Liens externes