Apakah dianggap sebagai anti-pola untuk membaca dari STDIN dari dalam perpustakaan?

39

Saat menulis perpustakaan untuk proyek besar yang sedang saya kerjakan di tempat kerja, muncul masalah yang membutuhkan token untuk dikirim ke alamat email, dan kemudian diteruskan kembali ke kode di mana ia kemudian dapat digunakan untuk penggunaan lebih lanjut.

Rekan saya mengatakan untuk hanya membaca dari STDIN (menggunakan Python:) code = input("Enter code: ")dan kemudian memiliki pengguna yang meneruskannya, namun bagi saya ini sepertinya praktik yang buruk karena perpustakaan mungkin (dalam hal ini pasti akan) digunakan dalam tugas latar belakang pada server .

Saya bertanya-tanya apakah ini dianggap sebagai anti-pola atau tidak.

Paradoksis
sumber
45
Tidak semuanya buruk adalah "anti-pola", meskipun ini tentu saja buruk.
Phoshi
4
"pattern" berarti sesuatu yang sering dilakukan oleh programmer. Ini hanya anti-pola jika keduanya (A) adalah ide yang buruk, dan (B) sesuatu yang Anda lihat dilakukan pengembang sepanjang waktu.
Solomon Slow
20
Ini terlalu bodoh untuk menjadi anti-pola. Anti-pola adalah sesuatu yang tampak alami dan masuk akal tetapi ternyata buruk ketika Anda menggali. Apa yang Anda gambarkan di sini jelas mengerikan.
Evan Harper
Saya tidak melihat inti dari salah satu jawaban. Inti dari latihan token pengguna harus membuktikan bahwa alamat email pengguna berfungsi. Jika bukan itu intinya, maka akan jauh lebih mudah untuk hanya menyimpan token.
emory
2
Ini sangat mengerikan. Jika melewatkan token seperti itu mutlak diperlukan, Anda dapat membuat executable terpisah menggunakan pustaka dan meneruskan token Anda ke stdin. Tetapi untuk membajak stdin dari executable panggilan, itu tidak-tidak.
GrandmasterB

Jawaban:

78

Sebagai pedoman umum, perpustakaan harus benar-benar terputus dari lingkungan. Itu berarti bahwa mereka tidak boleh melakukan operasi pada aliran standar, pada file tertentu, atau memiliki harapan tentang lingkungan atau konteks yang digunakan.

Tentu saja, ada pengecualian untuk aturan ini, tetapi harus ada alasan yang sangat bagus untuk itu. Dalam hal menggunakan stdin, saya tidak dapat menemukan alasan apa pun (kecuali perpustakaan Anda benar-benar menyediakan rutinitas untuk membaca dari stdin, seperti std::cindari C ++). Selain itu, mengambil stream I / O dari suatu parameter daripada meminta mereka melakukan hardcod menambahkan begitu banyak fleksibilitas sehingga tidak layak untuk tidak melakukannya.

Paul92
sumber
36
Pengecualian adalah perpustakaan yang memiliki tujuan spesifik untuk berinteraksi dengan lingkungan. Bahkan kemudian, perincian lingkungan harus disarikan. Misalnya, driver grafis harus berkomunikasi dengan bus PCIe, tetapi ID bus harus disediakan melalui konfigurasi.
Ini adalah jenis pengecualian yang saya pikir: ide saya lebih dekat dengan ncurses - umumnya, perpustakaan antarmuka pengguna teks-lingkungan. Jika tujuannya adalah untuk membaca input pengguna dan memberikan output pengguna, itu alasan yang bagus.
SF.
5
@ SF. Bahkan pustaka seperti ncurses harus menggunakan sepasang deskriptor file sebagai argumen daripada hardcoding penggunaan 0 dan 1. Anda mungkin ingin menulis sebuah program di mana stdin dan stdout dapat diarahkan dan bukannya Anda ingin membuka /dev/ttyuntuk berkomunikasi dengan pengguna. Program bahkan dapat dimulai tanpa terminal dan buka terminal sendiri menggunakan xterm -S.
kasperd
3
@kasperd: Pendekatan terbaik adalah menyediakan default yang masuk akal dan kemampuan untuk menimpanya.
SF.
1
Dalam kasus khusus ini, saya tidak melihat alasan untuk meminta aliran sebagai input. Mengapa tidak menerima token saja sebagai parameter?
jpmc26
16

Saya akan menganggap ini tidak harus anti-pola, hanya perpustakaan yang dirancang dengan buruk. Seharusnya sepele untuk meminta string sebagai parameter metode, di mana input dapat diteruskan secara langsung.

Jika itu tidak sesuai dengan penggunaan ini, maka parameter metode bisa menjadi streaming, dengan STDIN diteruskan ke dalam metode.

Jika itu tidak sesuai dengan penggunaan ini, maka perpustakaan tidak cukup fleksibel.

Bryan Boettcher
sumber
4

Mungkin mempertimbangkan memiliki kemampuan di perpustakaan Anda untuk mengatur panggilan balik ke fungsi yang disediakan pengguna yang akan membaca input dari mana saja , dan kemudian mengembalikan nilai yang sesuai kembali ke bagian perpustakaan mana pun yang menggunakan fungsi itu.

FrustratedWithFormsDesigner
sumber
1

Jika ia membaca dari stdin, itu berarti ia ingin mengambil kepemilikan tingkat program dari stdin. Kemungkinan tidak kompatibel dengan perpustakaan lain yang membaca dari stdin, protokol yang kurang spesifik untuk bagaimana mereka berbagi penggunaan. Setidaknya dalam glosarium pribadi saya sendiri, ini akan membuat perpustakaan menjadi kerangka kerja , yang merupakan tradeoff yang mahal.

Tetapi dalam kasus ini, perpustakaan mungkin harus hanya mengambil deskripsi file input.

Djechlin
sumber
0

Jawaban oleh @ Paul92 adalah diskusi umum yang baik, tetapi saya ingin menawarkan solusi bersih (ish) untuk ini:

Pustaka, kode ini harus dapat beradaptasi dengan lingkungan runtime, jadi Anda tidak bisa benar-benar meminta STDINsedikit data penting. Untuk satu, pengguna perpustakaan Anda mungkin tidak memiliki stdin tersedia karena sejumlah alasan. Alih-alih, Anda mungkin ingin menggunakan beberapa bentuk pola strategi untuk menyesuaikan cara token diambil.

Dalam Python, mungkin opsi terbaik adalah meneruskan strategi pengambilan token sebagai parameter fungsi. Sesuatu seperti itu:

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

Pikirkan seperti ini. Token yang Anda butuhkan, adalah argumen untuk fungsi perpustakaan. Karena nilai token mungkin tidak dikenal secara statis di situs panggilan, Anda tidak dapat benar-benar meminta nilai sebagai argumen. Sebaliknya, penelepon harus menyediakan fungsi yang akan bertanggung jawab untuk menyediakan token saat dipanggil.

Semua tanggung jawab untuk menyediakan mekanisme yang tepat dari token sekarang dieksternalisasi dari fungsi perpustakaan. Konsumen fungsi sekarang bertanggung jawab untuk memperoleh token dengan cara apa pun yang tersedia saat runtime. Mungkin bertanya STDIN, tetapi mungkin juga bertindak sebagai gateway email, menunggu pesan masuk ke kotak masuk, membacanya, mengekstrak token dan sepenuhnya mengotomatiskan proses. Mungkin dialog GUI atau formulir berbasis web. Apa pun yang benar - semua opsi kini ada di tangan konsumen perpustakaan.

Roland Tepp
sumber