Drôle, cette question m'a juste rappelé exactement la même conversation que j'ai eue avec l'un de nos ingénieurs à propos de la bibliothèque de communications sur laquelle je travaillais.
Au lieu de commandes, j'avais des classes Request et ensuite des RequestHandlers. Le design ressemblait beaucoup à ce que vous décrivez. Je pense qu'une partie de la confusion que vous avez est que vous voyez le mot anglais "command", et pensez instantanément "verb, action ... etc".
Mais dans cette conception, considérez la commande (ou la demande) comme une lettre. Ou pour ceux qui ne savent pas ce qu'est un service postal, pensez au courrier électronique. Il s'agit simplement d'un contenu, découplé de la manière dont ce contenu doit être appliqué.
Pourquoi voudriez-vous faire cela? Dans la plupart des cas simples, le modèle de commande n'a aucune raison et vous pouvez demander à cette classe d'effectuer le travail directement. Cependant, faire le découplage comme dans votre conception est logique si votre action / commande / demande doit parcourir une certaine distance. Par exemple, à travers, des sockets ou des tuyaux, ou entre le domaine et l'infrastructure. Ou peut-être que dans votre architecture, vos commandes doivent être persistantes (par exemple, le gestionnaire de commandes peut exécuter 1 commande à la fois, en raison de certains événements système, 200 commandes arrivent et après l'arrêt des 40 premiers processus). Dans ce cas, ayant une classe simple message uniquement, il devient très simple de sérialiser uniquement la partie message en JSON / XML / binaire / quoi que ce soit et de le transmettre dans le pipeline jusqu'à ce que son gestionnaire de commandes soit prêt à le traiter.
Un autre avantage du découplage de Command de CommandHandler est que vous avez maintenant la possibilité de disposer d'une hiérarchie d'héritage parallèle. Par exemple, toutes vos commandes peuvent dériver d'une classe de commandes de base qui prend en charge la sérialisation. Et peut-être que vous avez 4 gestionnaires de commande sur 20 qui ont beaucoup de similitudes, maintenant vous pouvez les dériver de la classe de base de gestionnaire venu. Si vous deviez gérer les données et les commandes dans une seule classe, ce type de relation deviendrait rapidement incontrôlable.
Un autre exemple de découplage serait si votre commande nécessitait très peu d'entrée (par exemple 2 entiers et une chaîne) mais que sa logique de gestion était suffisamment complexe pour que vous souhaitiez stocker des données dans les variables de membre intermédiaire. Si vous mettez en file d'attente 50 commandes, vous ne voulez pas allouer de mémoire pour tout ce stockage intermédiaire, vous séparez donc Command de CommandHandler. Maintenant, vous mettez en file d'attente 50 structures de données légères et le stockage de données plus complexe n'est alloué qu'une seule fois (ou N fois si vous avez N gestionnaires) par le CommandHandler qui traite les commandes.