¿Término (o "patrón"?) para "Hacer algo si aún no se ha hecho" [cerrado]

53

Suena bastante básico, lo sé, pero hace poco un colega me dijo que un método llamado startHttpServer es demasiado complicado de entender porque solo inicia el servidor si aún no se está ejecutando. Encuentro que me meto en problemas cuando respondo: "¿En serio? He estado haciendo esto durante décadas, es un patrón común en la programación". Más a menudo de lo que me importa admitir que regresa con alguna evidencia documentada que muestra que toda la comunidad de programación está detrás de su punto de vista y termino sintiéndome avergonzado.

Pregunta : ¿Existe un patrón de diseño documentado detrás del concepto de un método que no es operativo si la acción requerida ya está vigente? O, si no es un patrón, ¿tiene un nombre? Y si no, ¿hay alguna razón para pensar que es demasiado complicado considerar escribir un método de esta manera?

    
pregunta John Calcote 27.08.2017 - 08:10

8 respuestas

126

Como NickWilliams ya ha dicho : el concepto que describe el OP se llama idempotent (noun Idempotency ). De hecho, es una práctica común, especialmente en las API de alto nivel.

PERO: Renombra la función.

En lugar de startHttpServer , llámalo makeSureHttpServerIsRunning o ensureHttpServerIsRunning .

Cuando una función se llama startHttpServer , los lectores esperan que inicie un servidor HTTP; cuando sea llamado diez veces seguidas, tendré diez servidores en ejecución. Tu función no hace eso la mayor parte del tiempo. Además, el nombre con "inicio" sugiere que si quiero que solo se ejecute un servidor, tendré que hacer un seguimiento de si la función ya se ha llamado o no.

Cuando una función se llama makeSureHttpServerIsRunning , asumo que hará lo necesario para asegurarse de que se está ejecutando un servidor HTTP, lo más probable es que compruebe si ya se está ejecutando y que se inicie de otro modo. También asumo que la función se asegura de que el servidor se esté ejecutando realmente (el inicio de un servidor puede implicar un tiempo en el que aún no se está ejecutando).

    
respondido por el gnasher729 27.08.2017 - 09:45
32

Cambie su nombre a EnsureServerRunning .

Completamente inequívoco y está claro que se asegura de que se esté ejecutando (si no lo está) sin implicar un reinicio si lo está.

(Alternativa: StartServerIfNotRunning ?)

    
respondido por el Stilez 27.08.2017 - 13:26
28

No es realmente un patrón de diseño, pero llamaría a tu método idempotent . Este término se usa generalmente para referirse a llamadas remotas, pero la descripción parece coincidir con lo que está haciendo.

  

Métodos idempotentes. Los métodos también pueden tener la propiedad de   "idempotencia" en que (aparte de los problemas de error o vencimiento) la   efectos secundarios de N > 0 solicitudes idénticas son las mismas que para una sola   solicitud. ( De W3.org )

El efecto del servidor aquí es que el servidor http se inicia una vez que se llama al método. No veo nada malo con un método haciendo esto.

Si necesita un patrón de diseño, supongo que podría exponer su httpServer como un singleton que se inicia cuando se inicializa.

    
respondido por el Nick Williams 27.08.2017 - 09:12
7

Como quien implementa esta herramienta , startHttpServer , debe intentar que sea la más sencilla, fluida y perfecta para usar ...

La lógica de la función

Técnicamente, al dividir la lógica de startHttpServer en 2 funciones y llamándolas por separado , todo lo que haces es mover startHttpServer 's idempotency en el código que llama a ambas funciones en su lugar ... Además, a menos que incluya ambas lógicas en una tercera función ( que es lo que hace startHttpServer en primer lugar), esto te obliga a escribir código no DRY, duplicándolo exponencialmente en cualquier lugar al que tengas que llamar startHttpServer . En resumen, startHttpServer debe llamarse a sí misma la función isHttpServerRunning .

Así que mi punto es:

  • Implemente la función isHttpServerRunning porque de todas formas esto puede ser necesario de forma independiente ...
  • Implemente startHttpServer haciendo que use isHttpServerRunning para definir su siguiente acción en consecuencia ...

Aún así, puede hacer que startHttpServer devuelva cualquier valor que el usuario de esta función pueda necesitar, por ejemplo:

  • 0 = > error de inicio del servidor
  • 1 = > servidor de inicio exitoso
  • 2 = > el servidor ya fue iniciado

Nombre de la función

En primer lugar, ¿cuál es el objetivo principal del usuario? Para iniciar el servidor HTTP , ¿verdad?

Fundamentalmente, no hay ningún problema al intentar iniciar algo que ya se ha iniciado, AKA 1*1=1 . Entonces, al menos para mí, llamarlo " ensureHttpServerIsRunning " no parece ser una necesidad crítica, me preocuparía más sobre qué tan largo, natural y memorable es el nombre de la función.

Ahora, si desea saber cómo funciona en detalle la función bajo el capó, existe la fuente de la documentación o el código para eso, me refiero a cualquier otra función de library / framework / API / etc ...

Usted aprende la función una vez, mientras que la escribe varias veces ...

De todos modos, me quedaría con startHttpServer que es más corto, más simple y más explícito que ensureHttpServerIsRunning .

    
respondido por el ClemC 27.08.2017 - 14:26
2

Supongo que su colega quiso decir que startHttpServer está haciendo demasiado:

  • Comprobando si el servidor ya se está ejecutando,
  • Iniciar el servidor si es necesario.

Esas son dos partes no relacionadas del código. Por ejemplo, existe una situación similar cuando una aplicación de escritorio debe garantizar que no se está ejecutando cuando se inicia; habrá una parte del código que gestiona las instancias de la aplicación (por ejemplo, mediante un mutex) y el código que iniciará el bucle de mensajes de la aplicación.

Esto significa que no debes tener uno, sino al menos dos métodos :

  • isHttpServerRunning: boolean
  • startHttpServer

El punto de entrada de la aplicación llamará al primer método y luego al segundo si el valor de retorno es false . Ahora, cada método está haciendo una y una cosa, y es fácil de entender.

¹ Si la lógica necesaria para saber si el servidor ya se está ejecutando es demasiado compleja, puede requerir una mayor separación en varios métodos.

    
respondido por el Arseni Mourzenko 27.08.2017 - 08:53
2

Como no especifica un idioma, en JavaScript muchas bibliotecas tienen la función "once" por ejemplo Subrayado . Por lo tanto, si eso le resultara familiar, llámelo "una vez" y posiblemente cambie el nombre de su método.

Yo mismo, viniendo más de Java, los términos "almacenamiento en caché" o "evaluación perezosa" vienen a la mente. "Idempotent" es técnicamente correcto y una buena opción, especialmente. Si tienes un fondo más funcional.

    
respondido por el user949300 28.08.2017 - 18:02
-2

Prefiero startHttpServerIfNotIsRunning .

De esta manera, la condición se menciona claramente ya en el nombre del método. Ensure o makeSure me parece un tanto vago, ya que no es una expresión técnica. Parece que no sabemos exactamente qué va a pasar.

    
respondido por el Herr Derb 28.08.2017 - 10:24
-3

Lo que su colega debería haberle dicho es que no tiene nada que ver con escribir ese método. Ya se ha escrito muchas veces y se ha escrito mejor de lo que es probable que lo escribas. Por ejemplo: enlace enlace

Desde una perspectiva arquitectónica, tener un poco de código arbitrario para administrar un servidor web es cosa de pesadillas. A menos que la administración de servicios sea exclusivamente lo que hace su código. Pero supongo que no escribiste monit (o kubernetes o ...).

    
respondido por el Andrew 28.08.2017 - 18:10

Lea otras preguntas en las etiquetas