Podczas pisania biblioteki dla dużego projektu, nad którym pracuję w pracy, pojawił się problem, który wymagał wysłania tokena na adres e-mail, a następnie przesłania go z powrotem do kodu, z którego można go następnie wykorzystać.
Mój kolega mówi, że po prostu czytam ze STDIN (używając Pythona:), code = input("Enter code: ")
a następnie przekazuję go użytkownikowi, jednak wydaje mi się, że jest to zła praktyka, ponieważ biblioteka może (w tym przypadku na pewno będzie) używana w zadaniu w tle na serwerze .
Zastanawiałem się, czy uznano to za anty-wzór, czy nie.
programming-practices
libraries
anti-patterns
Paradoksy
źródło
źródło
Odpowiedzi:
Zasadniczo biblioteki powinny być całkowicie odłączone od środowiska. Oznacza to, że nie powinni wykonywać operacji na standardowych strumieniach, określonych plikach ani mieć żadnych oczekiwań co do środowiska lub kontekstu, w którym są używane.
Oczywiście są wyjątki od tej reguły, ale musi być bardzo dobry powód. W przypadku używania
stdin
nie mogę znaleźć żadnego powodu (chyba że twoja biblioteka faktycznie udostępnia procedury do czytania ze standardowego wejścia, np.std::cin
Z C ++). Ponadto wzięcie strumieni we / wy z parametru zamiast zakodowania ich na sztywno zapewnia tak dużą elastyczność, że nie warto tego robić.źródło
/dev/tty
w celu komunikacji z użytkownik. Program można nawet uruchomić bez terminala i otworzyć własny terminal za pomocąxterm -S
.Uznałbym, że niekoniecznie jest to anty-wzór, tylko źle zaprojektowana biblioteka. Pytanie o ciąg znaków jako parametr metody powinno być trywialne, w którym dane wejściowe mogłyby być przekazywane bezpośrednio do.
Jeśli to nie pasuje do tego zastosowania, parametrem metody może być strumień, z STDIN przekazanym do metody.
Jeśli to nie pasuje do tego zastosowania, biblioteka nie jest wystarczająco elastyczna.
źródło
Może warto rozważyć możliwość ustawienia w bibliotece wywołania zwrotnego do funkcji podanej przez użytkownika, która odczyta dane wejściowe z dowolnego miejsca , a następnie zwróci odpowiednią wartość z powrotem do dowolnej części biblioteki, która korzysta z tej funkcji.
źródło
Jeśli odczytuje stdin, oznacza to, że chciałby przejąć własność stdin na poziomie programu. Prawdopodobnie nie jest kompatybilny z żadną inną biblioteką odczytującą ze standardowego, mniej szczegółowego protokołu dotyczącego sposobu ich wspólnego użytkowania. W moim osobistym glosariuszu uczyniłoby to bibliotekę ramową , co jest kosztownym kompromisem.
Ale w tym przypadku biblioteka powinna po prostu wziąć deskryptor pliku wejściowego.
źródło
Odpowiedź @ Paul92 to dobra ogólna dyskusja, ale chciałbym zaoferować możliwe czyste (ish) rozwiązanie tego:
Biblioteka, ten kod musi być dostosowywany do dowolnego środowiska wykonawczego, więc nie można tak naprawdę poprosić
STDIN
o jakiś kluczowy fragment danych. Po pierwsze, użytkownicy twojej biblioteki mogą nie mieć standardowego wejścia z wielu powodów. Zamiast tego możesz użyć jakiejś formy wzorca strategii , aby dostosować sposób odzyskiwania tokena.W Pythonie prawdopodobnie najlepszą opcją jest przekazanie strategii pobierania tokena jako parametru funkcji. Coś w tym stylu:
Pomyśl o tym w ten sposób. Wymagany token jest argumentem funkcji bibliotecznej. Ponieważ wartość tokena może nie być statycznie znana w witrynie wywołującej, nie można tak naprawdę prosić o wartość jako argument. Zamiast tego, osoba dzwoniąca musi zapewnić funkcję, która będzie odpowiedzialna za dostarczenie tokena po wywołaniu.
Cała odpowiedzialność za podanie dokładnej mechaniki tokena jest teraz uzewnętrzniona z funkcji biblioteki. Odbiorca funkcji jest teraz odpowiedzialny za pozyskiwanie tokena za pomocą wszelkich dostępnych środków w czasie wykonywania. Może zapytać STDIN, ale może również działać jako brama pocztowa, czekać na wiadomość w skrzynce odbiorczej, czytać ją, wyodrębniać token i całkowicie zautomatyzować proces. Może to być okno dialogowe GUI lub formularz internetowy. Coś naprawdę - wszystkie opcje są teraz w rękach konsumenta biblioteki.
źródło