Mientras escribía una biblioteca para un gran proyecto 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 pasar al código donde luego se puede usar para su uso posterior.
Mi colega dice que solo lea STDIN (usando Python:) code = input("Enter code: ")
y luego haga que un usuario lo pase, sin embargo, para mí esto parece una mala práctica ya que la biblioteca podría (en este caso definitivamente) usarse en una tarea en segundo plano en un servidor .
Me preguntaba si esto se consideraba un antipatrón o no.
Respuestas:
Como pauta general, las bibliotecas deben estar totalmente desconectadas del entorno. Eso significa que no deben realizar operaciones en transmisiones estándar, en archivos específicos, ni tener ninguna 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, comostd::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.fuente
/dev/tty
para comunicarse con el usuario. El programa podría incluso iniciarse sin un terminal y abrir su propio terminal usandoxterm -S
.Consideraría que esto no es necesariamente un antipatrón, solo una biblioteca mal diseñada. Debería ser trivial pedir una cadena como parámetro de método, donde la entrada podría pasarse 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.
fuente
Tal vez considere tener la capacidad en su biblioteca de establecer una devolución de llamada a una función proporcionada por el usuario que leerá la entrada desde cualquier lugar y luego devolverá el valor apropiado a cualquier parte de la biblioteca que esté usando esa función.
fuente
Si lee de stdin, significa que le gustaría tomar posesión de stdin a nivel de programa. Es probable que no sea compatible con ninguna otra biblioteca que lea desde stdin, un protocolo menos específico sobre cómo comparten el uso. Al menos en mi propio glosario personal, esto convertiría a la biblioteca en un marco , lo cual es una compensación costosa.
Pero en este caso, la biblioteca probablemente solo debería tomar un descriptor de archivo de entrada.
fuente
La respuesta de @ Paul92 es una buena discusión general, pero me gustaría ofrecer una posible solución limpia (ish) a esto:
Como una biblioteca, este código debe ser adaptable a cualquier entorno de tiempo de ejecución, por lo que realmente no puede solicitar
STDIN
algunos datos cruciales. Por un lado, los usuarios de su biblioteca podrían no tener stdin disponible por varias razones. 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 recuperación de tokens como un parámetro de función. Algo como eso:
Piensa en esto, de esta manera. El token que necesita es un argumento para la función de biblioteca. Dado que el valor del token puede no ser conocido estáticamente en el sitio de la llamada, realmente no puede solicitar el valor como argumento. En cambio, la persona que llama tiene que 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 el mensaje aparezca en la bandeja de entrada, leerlo, extraer el token y automatizar completamente el proceso. Puede ser un cuadro de diálogo GUI o un formulario basado en web. Cualquier cosa realmente: todas las opciones están ahora en manos del consumidor de la biblioteca.
fuente