É considerado um antipadrão para ler STDIN dentro de uma biblioteca?

39

Enquanto escrevia uma biblioteca para um grande projeto no qual estou trabalhando, surgiu um problema que exigia que um token fosse enviado para um endereço de e-mail e depois devolvido para o código, onde ele poderia ser usado posteriormente. usar.

Meu colega diz apenas para ler a partir de STDIN (usando Python: code = input("Enter code: ") ) e então fazer um usuário passá-lo, mas para mim isso parece uma prática ruim, pois a biblioteca pode (neste caso, definitivamente) ser usada em uma tarefa em segundo plano em um servidor.

Eu queria saber se isso era ou não considerado um anti-padrão ou não.

    
por Paradoxis 24.02.2017 / 16:13
fonte

5 respostas

78

Como orientação geral, as bibliotecas devem estar totalmente desconectadas do ambiente. Isso significa que eles não devem executar operações em fluxos padrão, em arquivos específicos ou ter qualquer expectativa sobre o ambiente ou o contexto em que são usados.

Claro, há exceções a essa regra, mas deve haver uma boa razão para isso. No caso de usar stdin , não consigo encontrar nenhum motivo (a menos que sua biblioteca realmente forneça rotinas para leitura de stdin, como std::cin de C ++). Além disso, pegar os fluxos de E / S de um parâmetro em vez de tê-los codificados adiciona muita flexibilidade, e não vale a pena não fazê-lo.

    
por 24.02.2017 / 16:38
fonte
16

Eu consideraria isso não necessariamente um antipadrão, apenas uma biblioteca mal projetada. Deve ser trivial pedir uma string como um parâmetro de método, onde a entrada pode ser passada diretamente.

Se isso não se encaixa nesse uso, um parâmetro de método pode ser um fluxo, com STDIN passado para o método.

Se isso não se encaixa nesse uso, a biblioteca não é flexível o suficiente.

    
por 24.02.2017 / 16:21
fonte
5

Talvez considere ter a capacidade em sua biblioteca de definir um retorno de chamada para uma função fornecida pelo usuário que lerá entradas de onde e, em seguida, retornará o valor apropriado para qualquer parte da biblioteca. essa função.

    
por 24.02.2017 / 20:19
fonte
1

Se ele ler de stdin, isso significa que você gostaria de obter a propriedade do stdin no nível do programa. É provável que não seja compatível com qualquer outra biblioteca que leia o protocolo stdin, menos específico, sobre como eles compartilham o uso. Pelo menos no meu próprio glossário pessoal, isso tornaria a biblioteca um framework , o que é um tradeoff caro.

Mas, neste caso, a biblioteca deve provavelmente pegar um descritor de arquivo de entrada.

    
por 24.02.2017 / 20:24
fonte
0

A resposta de @Paul92 é boa discussão geral, mas eu gostaria de oferecer uma possível solução clean (ish) para isso:

Como uma biblioteca, esse código precisa ser adaptável a qualquer ambiente de tempo de execução, portanto, você não pode realmente pedir STDIN para algum bit de dados crucial. Por um lado, os usuários de sua biblioteca podem não ter stdin disponível por vários motivos. Em vez disso, você pode querer usar alguma forma de padrão estratégia para personalizar como o token deve ser recuperado.

No Python, provavelmente a melhor opção é passar a estratégia de busca de tokens como um parâmetro de função. Algo assim:

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")

Pense nisso assim. O token que você precisa é um argumento para a função da biblioteca. Como o valor do token pode não ser estaticamente conhecido no site de chamada, você não pode realmente solicitar o valor como um argumento. Em vez disso, o chamador deve fornecer uma função que será responsável por fornecer o token quando chamado.

Toda a responsabilidade de fornecer a mecânica exata do token é agora externalizada da função de biblioteca. O consumidor da função agora é responsável por adquirir o token por qualquer meio que esteja disponível em tempo de execução. Ele pode perguntar ao STDIN, mas também pode funcionar como um gateway de correio, aguardar que a mensagem seja exibida na caixa de entrada, ler, extrair o token e automatizar completamente o processo. Pode ser uma caixa de diálogo da GUI ou um formulário baseado na web. Qualquer coisa realmente - todas as opções estão agora nas mãos do consumidor da biblioteca.

    
por 06.03.2017 / 12:26
fonte