È considerato un anti-pattern per leggere da STDIN all'interno di una libreria?

39

Mentre scrivevo una libreria per un progetto di grandi dimensioni su cui sto lavorando al lavoro, è emerso un problema che richiedeva l'invio di un token a un indirizzo e-mail, quindi il codice passato dove può essere utilizzato per ulteriori utilizzare.

Il mio collega dice di leggere da STDIN (usando Python: code = input("Enter code: ") ) e poi far passare un utente, tuttavia a me sembra una cattiva pratica dato che la libreria potrebbe (in questo caso sicuramente lo sarà) in un'attività in background su un server.

Mi chiedevo se questo fosse considerato un anti-pattern o no.

    
posta Paradoxis 24.02.2017 - 16:13
fonte

5 risposte

78

Come linea guida generale, le biblioteche dovrebbero essere totalmente disconnesse dall'ambiente. Ciò significa che non devono eseguire operazioni su flussi standard, su file specifici o avere aspettative sull'ambiente o sul contesto in cui vengono utilizzati.

Naturalmente, ci sono delle eccezioni a questa regola, ma ci deve essere una buona ragione per farlo. Nel caso dell'utilizzo di stdin , non riesco a trovare alcun motivo (a meno che la tua libreria non fornisca effettivamente le routine per la lettura da stdin, come std::cin da C ++). Inoltre, prendere i flussi I / O da un parametro piuttosto che averli codificati in modo fisso aggiunge tanta flessibilità che non vale la pena di non eseguirlo.

    
risposta data 24.02.2017 - 16:38
fonte
16

Considererei questo non necessariamente un anti-pattern, solo una libreria mal progettata. Dovrebbe essere banale chiedere una stringa come parametro del metodo, in cui l'input può essere passato direttamente.

Se ciò non corrisponde a questo utilizzo, un parametro metodo può essere un flusso, con STDIN passato al metodo.

Se non si adatta a questo utilizzo, la libreria non è abbastanza flessibile.

    
risposta data 24.02.2017 - 16:21
fonte
5

Forse consideri di avere l'abilità nella tua libreria di impostare un callback per una funzione fornita dall'utente che leggerà l'input da ovunque , e poi restituirà il valore appropriato a qualunque parte della libreria stia usando quella funzione.

    
risposta data 24.02.2017 - 20:19
fonte
1

Se legge da stdin, significa che vorrebbe prendere la proprietà a livello di programma di stdin. Probabilmente non è compatibile con altre librerie che leggono da stdin, protocollo meno specifico per il modo in cui condividono l'uso. In almeno il mio glossario personale, ciò renderebbe la libreria un framework , che è un compromesso costoso.

Ma in questo caso, la libreria dovrebbe probabilmente solo prendere un descrittore di file di input.

    
risposta data 24.02.2017 - 20:24
fonte
0

La risposta di @ Paul92 è una buona discussione generale, ma vorrei offrire una possibile soluzione clean (ish) a questo:

Una libreria, questo codice deve essere adattabile a qualsiasi ambiente di runtime, quindi non puoi davvero chiedere STDIN per alcuni bit cruciali di dati. Per uno, gli utenti della tua libreria potrebbero non avere lo stdin disponibile per una serie di motivi. Invece, potresti voler usare qualche forma di modello strategia per personalizzare il modo in cui il token deve essere recuperato.

In Python, probabilmente l'opzione migliore è passare la strategia di recupero dei token come parametro di funzione. Qualcosa del genere:

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

Pensa in questo modo. Il token richiesto è un argomento della funzione di libreria. Poiché il valore del token potrebbe non essere statisticamente noto nel sito di chiamata, non è possibile chiedere realmente il valore come argomento. Invece, il chiamante deve fornire una funzione che sarà responsabile della fornitura del token quando chiamato.

Tutta la responsabilità di fornire la meccanica esatta del token è ora esternalizzata dalla funzione di libreria. Il consumatore della funzione è ora responsabile dell'acquisizione del token con qualsiasi mezzo disponibile in fase di runtime. Può chiedere a STDIN, ma potrebbe anche fungere da gateway di posta, attendere che il messaggio compaia nella casella di posta, leggerlo, estrarre il token e automatizzare completamente il processo. Potrebbe essere una finestra di dialogo della GUI o un modulo basato sul web. Qualcosa di veramente - tutte le opzioni sono ora nelle mani del consumatore della biblioteca.

    
risposta data 06.03.2017 - 12:26
fonte

Leggi altre domande sui tag