Cela paraît assez basique, je le sais, mais un collègue m'a récemment dit qu'une méthode appelée startHttpServer
est trop compliquée à comprendre, car elle ne démarre le serveur que si elle n'est pas déjà en cours d'exécution. Je trouve que j'ai des problèmes lorsque je réponds avec "Sérieusement? Je le fais depuis des décennies - c'est un modèle courant en programmation." Plus souvent que je ne tiens à l'admettre, il revient avec des preuves documentées qui montrent que toute la communauté de la programmation est en retard sur son point de vue et que je finis par me sentir penaud.
Question : Existe-t-il un modèle de conception documenté derrière le concept d'une méthode qui est une non-opération si l'action requise est déjà effective? Ou, si ce n'est un motif, a-t-il un nom non plus? Et si non, y a-t-il une raison de penser que c'est trop compliqué d'envisager l'écriture d'une méthode de cette manière?
la source
startHttpServer
), et oui, le terme "idempotent" s'applique ici bien.Réponses:
Comme NickWilliams l' a déjà dit : le concept décrit par l'OP s'appelle idempotent (nom Idempotency ). C'est en effet une pratique courante, en particulier dans les API de haut niveau.
MAIS: Renommez la fonction.
Au lieu de l'
startHttpServer
appelermakeSureHttpServerIsRunning
ouensureHttpServerIsRunning
.Lorsqu'une fonction est appelée
startHttpServer
, les lecteurs s'attendent à ce qu'elle lance un serveur HTTP. Lorsque je serai appelé dix fois de suite, je ferai fonctionner dix serveurs. Votre fonction ne le fait pas la plupart du temps. De plus, le nom avec "start" suggère que si je ne souhaite utiliser qu'un seul serveur, je devrai savoir si la fonction a déjà été appelée ou non.Quand une fonction est appelée
makeSureHttpServerIsRunning
, je suppose qu’elle fera les choses nécessaires pour s’assurer qu’un serveur HTTP est en cours d’exécution, le plus souvent en vérifiant s’il est déjà en cours d’exécution et en le démarrant sinon. Je suppose également que la fonction permet de s’assurer que le serveur est en cours d’exécution (le démarrage d’un serveur peut impliquer un certain temps où il n’est pas encore en cours d’exécution).la source
Renommez le en
EnsureServerRunning
.Complètement sans ambiguïté et il est clair qu’il s’assure qu’il est en cours d’exécution (si ce n’est pas le cas) sans impliquer de redémarrage, le cas échéant.
(Alternative
StartServerIfNotRunning
:?)la source
Ce n'est pas vraiment un motif, mais j'appellerais votre méthode idempotente . Ce terme est généralement utilisé pour désigner les appels distants, mais la description semble correspondre à ce que vous faites.
L'effet côté serveur étant que le serveur http est démarré une fois la méthode appelée. Je ne vois rien de mal à ce qu'une méthode le fasse.
Si vous avez besoin d’un modèle, j’imagine que vous pouvez exposer votre httpServer en tant que singleton qui est lancé à l’initialisation.
la source
Comme celui qui mettent en œuvre cet outil ,
startHttpServer
vous devriez essayer de faire le plus simple, lisse et transparente à l' utilisation ...La logique de la fonction
Techniquement, en scindant
startHttpServer
la logique en 2 fonctions et en les appelant séparément , tout ce que vous faites est de déplacerstartHttpServer
l’ idempotency dans le code en appelant les deux fonctions à la place ...startHttpServer
en premier lieu), cela vous oblige à écrire du code unDRYed, en le dupliquant de manière exponentielle partout où vous auriez à appelerstartHttpServer
. En bref,startHttpServer
doit s'appeler elle-même laisHttpServerRunning
fonction.Donc, mon point est:
isHttpServerRunning
fonction parce que cela peut être nécessaire indépendamment de toute façon ...startHttpServer
faisant utiliserisHttpServerRunning
pour définir sa prochaine action en conséquence ...Cependant, vous pouvez toujours
startHttpServer
renvoyer toute valeur dont l'utilisateur de cette fonction peut avoir besoin, par exemple:0
=> échec de démarrage du serveur1
=> succès de démarrage du serveur2
=> le serveur a déjà été démarréLe nom de la fonction
Tout d’abord, quel est le but principal de l’utilisateur? Pour démarrer le serveur HTTP , non?
Fondamentalement, il n'y a pas de problème en envisageant de commencer quelque chose qui a déjà été commencé, AKA
1*1=1
. Donc, du moins pour moi, l'appeler "ensureHttpServerIsRunning
" ne semble pas être absolument nécessaire, je me soucierais davantage de la longueur, du naturel et du mémorable nom de la fonction.Maintenant, si vous voulez savoir comment fonctionne la fonction sous le capot en détail, il y a la documentation ou le code source pour cela, je veux dire comme pour toute autre fonction de la bibliothèque / framework / API / etc ...
Vous apprenez la fonction une fois pendant que vous l' écrivez plusieurs fois ...
De toute façon, je m'en tiendrai à
startHttpServer
ce qui est plus court, plus simple et plus explicite queensureHttpServerIsRunning
.la source
Je suppose que votre collègue voulait dire que cela en
startHttpServer
faisait trop:Ce sont deux parties de code non liées. Par exemple, une situation similaire se présente lorsqu'une application de bureau doit s'assurer qu'elle n'est pas déjà en cours d'exécution lorsqu'elle est lancée. une partie du code gère les instances d'application (par exemple, à l'aide d'un mutex) et le code qui lance la boucle de message d'application.
Cela signifie que vous ne devez pas avoir une, mais au moins une, deux méthodes :
isHttpServerRunning: boolean
startHttpServer
Le point d’entrée de l’application appelle la première méthode, puis la seconde si la valeur renvoyée est
false
. Désormais, chaque méthode fait une chose et est facile à comprendre.¹ Si la logique nécessaire pour savoir si le serveur est déjà en cours d’exécution est trop complexe, une séparation supplémentaire en plusieurs méthodes peut être nécessaire.
la source
startHttpServer
on appelle plus d'une place dans le code? Est-ce que plusieurs lignes similaires doivent être copiées-collées partout? Cela devrait-il être fait avec toutes les fonctions? Bientôt, votre programme aura une taille infinie.startHttpServer
méthode ressemblera à peu prèsif (isHttpServerRunning()){ return; }
. Vous affirmez une règle de gestion selon laquelle "il n'est pas correct de démarrer le serveur http s'il est déjà en cours d'exécution", mais vous obligez alors une autre personne à appliquer cette règle. Ad-hoc et à plusieurs reprises à chaque endroit où ils pourraient appelerstartHttpServer
.Puisque vous ne spécifiez pas de langue, de nombreuses bibliothèques en JavaScript ont une fonction "une fois", par exemple, Underscore . Donc, si cela vous est familier, appelez-le un motif "une fois" et renommez éventuellement votre méthode.
Moi-même, venant davantage de Java, je pense aux termes "mise en cache" ou "évaluation paresseuse". "Idempotent" est techniquement correct et constitue un bon choix, en particulier. si vous avez un fond plus fonctionnel.
la source
restartHttpServer()
méthode rarement utilisée . Mais juste arrêter - quel est le cas d'utilisation ici? Vous aimez les échecs de connexion sporadiques? :-)ensureRunning()
? :-) En ce qui concerne l’arrêt de l’administrateur, le fait de redémarrer constamment cet autre code pendant que l’administrateur essaie de modifier ou de corriger quelque chose serait incroyablement ennuyant et erroné. Laissez l'administrateur le redémarrer, pas le code.Je préférerais
startHttpServerIfNotIsRunning
.De cette façon, la condition est clairement mentionnée déjà dans le nom de la méthode.
Ensure
oumakeSure
me semble un peu vague, car ce n’est pas une expression technique. On dirait que nous ne savons pas exactement ce qui va se passer.la source
Ensure
signifie. Je n'aime toujours pas ce mot pour une expression technique.Ensure
est quelque chose d'humain. Un système ne peut rien garantir, il ne fera que ce qu'il est censé faire.Ce que votre collègue aurait dû vous dire, c'est que vous n'avez pas à écrire cette méthode. Il a déjà été écrit maintes fois et mieux que vous ne l'auriez probablement écrit. Par exemple: http://docs.ansible.com/ansible/latest/systemd_module.html https://docs.saltstack.com/en/latest/ref/states/all/salt.states.service.html
D'un point de vue architectural, la gestion d'un serveur Web par un morceau de code arbitraire est un véritable cauchemar. Sauf si la gestion des services est exclusivement ce que fait votre code. Mais je suppose que vous n'avez pas écrit monit (ou kubernetes ou ...).
la source
startServer
fonction ou similaire est tout à fait inhabituel . Cela ne signifie pas que vous écrirez les détails de bas niveau.