¿Se considera un antipatrón para leer desde STDIN desde una biblioteca?

39

Mientras escribía una biblioteca para un proyecto grande en el que estoy trabajando en el trabajo, surgió un problema que requería que se enviara un token a una dirección de correo electrónico y luego se volviera a introducir en el código, donde luego se puede usar para más información. utilizar.

Mi colega dice que simplemente lea desde STDIN (usando Python: code = input("Enter code: ") ) y luego pídale a un usuario que lo pase, sin embargo, para mí esto es una mala práctica ya que la biblioteca podría (en este caso definitivamente) ser usada en una tarea en segundo plano en un servidor.

Me preguntaba si esto se consideraba un antipatrón o no.

    
pregunta Paradoxis 24.02.2017 - 16:13

5 respuestas

78

Como norma general, las bibliotecas deben estar totalmente desconectadas del entorno. Eso significa que no deben realizar operaciones en secuencias estándar, en archivos específicos, o tener alguna expectativa sobre el entorno o el contexto en el que se utilizan.

Por supuesto, hay excepciones a esta regla, pero debe haber una muy buena razón para ello. En el caso de usar stdin , no puedo encontrar ninguna razón (a menos que su biblioteca realmente proporcione rutinas para leer desde stdin, como std::cin desde C ++). Además, tomar las secuencias de E / S de un parámetro en lugar de tenerlas codificadas agrega tanta flexibilidad que no vale la pena no hacerlo.

    
respondido por el Paul92 24.02.2017 - 16:38
16

Considero que esto no es necesariamente un anti-patrón, solo una biblioteca mal diseñada. Debería ser trivial solicitar una cadena como parámetro de método, donde la entrada se podría pasar directamente.

Si eso no se ajusta a este uso, entonces un parámetro del método puede ser una secuencia, con STDIN pasado al método.

Si eso no se ajusta a este uso, entonces la biblioteca no es lo suficientemente flexible.

    
respondido por el Bryan Boettcher 24.02.2017 - 16:21
5

Tal vez considere tener la capacidad en su biblioteca para establecer una devolución de llamada a una función proporcionada por el usuario que leerá la entrada de en cualquier lugar , y luego devolverá el valor apropiado a cualquier parte de la biblioteca que esté usando esa función.

    
respondido por el FrustratedWithFormsDesigner 24.02.2017 - 20:19
1

Si se lee desde la entrada estándar, significa que le gustaría tomar posesión del nivel de programa de la entrada estándar. Es probable que no sea compatible con ninguna otra biblioteca que lea desde stdin, un protocolo menos específico para la forma en que comparten el uso. Al menos en mi propio glosario personal, esto haría de la biblioteca un framework , lo que es una compensación costosa.

Pero en este caso, la biblioteca probablemente debería tomar un descriptor de archivo de entrada.

    
respondido por el djechlin 24.02.2017 - 20:24
0

La respuesta de @ Paul92 es una buena discusión general, pero me gustaría ofrecer una posible solución limpia (ish) para esto:

Una biblioteca, este código debe ser adaptable a cualquier entorno de tiempo de ejecución, por lo que realmente no puede pedir a STDIN algunos datos cruciales. Por un lado, es posible que los usuarios de su biblioteca no tengan disponible la entrada estándar por varios motivos. En su lugar, es posible que desee utilizar algún tipo de patrón de estrategia para personalizar cómo se recuperará el token.

En Python, probablemente la mejor opción es pasar la estrategia de búsqueda de tokens como parámetro de función. Algo así:

def stdin_prompt():
    return input("Enter code: ")

def my_library_function(arg1, arg2, ... argn, token_provider = stdin_prompt):
    ...
    token = token_provider()
    ...
    return stuff

# somewhere in the user code
stuff = my_library_function(a1, a2, ... an, lambda: "123456")

Piénsalo así. El token que necesita, es un argumento de la función de biblioteca. Dado que el valor para el token puede no ser conocido de forma estática en el sitio de la llamada, realmente no se puede pedir el valor como un argumento. En su lugar, la persona que llama debe proporcionar una función que será responsable de proporcionar el token cuando se le llame.

Toda la responsabilidad de proporcionar la mecánica exacta del token ahora se externaliza desde la función de biblioteca. El consumidor de la función ahora es responsable de adquirir el token por cualquier medio disponible en tiempo de ejecución. Puede solicitar STDIN, pero también puede actuar como una puerta de enlace de correo, esperar a que aparezca el mensaje en la bandeja de entrada, leerlo, extraer el token y automatizar completamente el proceso. Puede ser un diálogo GUI o un formulario basado en web. En realidad, todas las opciones están ahora en manos del consumidor de la biblioteca.

    
respondido por el Roland Tepp 06.03.2017 - 12:26

Lea otras preguntas en las etiquetas