web-dev-qa-db-fra.com

Comment éviter de nombreux objets dans les constructeurs lorsque de nombreuses étapes sont effectuées par une classe

J'ai un processus qui doit faire 8 étapes, dans un ordre particulier. L'une des étapes consiste à envoyer un e-mail, un autre sur un serveur FTP distant, un autre interrogeant une base de données, etc. Maintenant, pour pouvoir tester ces 8 étapes, chacune d'elles est une méthode dans une classe distincte. Jusqu'ici tout va bien.

Maintenant, le problème auquel je suis confronté est que la classe "parent" qui appelle les étapes reçoit maintenant dans ses classes constructeur 8, ce qui est clairement une odeur de code ici. Vous pourriez me dire: hé, créez simplement une classe avec les 4 premières étapes, et une autre avec les 4 autres, et le parent recevra simplement deux classes dans son constructeur. Dans mon esprit, cela me semble également mal - j'ai l'impression que j'ajoute de la complexité et ne résout pas vraiment le problème.

Existe-t-il un modèle de conception ou une autre technique à utiliser lorsque de nombreuses étapes doivent être appelées par une classe?

5
user1861857

Si la classe est vraiment simplifiée au point qu'elle ne fait que fournir une séquence contrôlée aux opérations, et que la complexité de chaque opération est gérée par les classes dépendantes, alors je ne pense pas qu'il y ait ici un problème à résoudre.

Si la séquence d'opérations pour ce processus est vraiment de 8 étapes, alors le constructeur avec 8 dépendances expose adéquatement la complexité du processus.

Si quelque chose devait être envisagé pour la refactorisation, ce devrait être le processus lui-même. Peut-il être simplifié? Peut-il prendre moins de mesures? Sinon, c'est aussi simple/complexe que nécessaire et le constructeur de la classe de coordination devrait le refléter.

Essayer de masquer la complexité nécessaire à travers des regroupements d'étapes arbitraires serait une odeur de code pire qu'un grand constructeur.

9
Eric King

Suite à la réponse d'Eric King qui est un bon avertissement.

Si vous devez séquencer une série d'opérations, demandez-vous si elles sont suffisamment similaires pour que vous puissiez leur donner une interface commune qui pourrait être invoquée - de telle sorte que vous puissiez les traiter comme une collection de tâches abstraites.

Une autre chose à considérer est de savoir si vous pourriez avoir besoin de changer ou de désactiver l'une des parties - lorsque vous voulez la changer - il pourrait devenir plus évident de savoir comment vous souhaitez réorganiser les choses.

Votre solution a la même "forme" que le problème, ce qui est souvent un bon signe.

3
Jamie

Y a-t-il une interaction entre les 8 classes? Sinon, une possibilité serait que vos 8 classes implémentent toutes une interface avec la fonction unique doTheThing() (exemple de nom de fonction hilarant, veuillez ne pas l'utiliser dans du code réel), alors vous pourriez les passer dans un IList au lieu de huit paramètres distincts. Votre classe "parent" n'a alors plus qu'à parcourir cette liste, en appelant doTheThing() pour chaque membre.

0
Pete