STDIN'den bir kütüphaneden okumak için anti-pattern olarak mı kabul edilir?


39

İşteyken üzerinde çalıştığım büyük bir proje için bir kütüphane yazarken, bir belirtecin bir e-posta adresine gönderilmesini gerektiren ve daha sonra kullanılmak üzere kullanılabileceği koda geri gönderilen bir sorun ortaya çıktı.

Meslektaşım sadece STDIN'den (Python kullanarak code = input("Enter code: ")) okuduğunu ve daha sonra bir kullanıcının bunu ilettiğini söylüyor , ancak bana göre bu, kütüphanenin bir sunucudaki arka plan görevinde kullanılabileceği gibi kötü bir uygulama gibi görünüyor. .

Bunun bir anti-patern olarak değerlendirilip değerlendirilmediğini merak ediyordum.


45
Kötü olan her şey bir "anti-kalıp" değildir, ancak bu kesinlikle kötüdür.
Phoshi

4
"kalıp", programcıların sıkça yaptığı bir şey anlamına gelir. Bu sadece (A) kötü bir fikir ve (B) geliştiricilerin her zaman yaptıklarını gördüğünüz bir şeyse, anti-paterndir.
Süleyman Yavaş

20
Bu bir anti-patern olmak için çok aptalca. Anti-patern, doğal ve mantıklı görünen bir şeydir, ancak onu kazarken kötü görünür. Burada tarif ettiğin şey kesinlikle çok korkunç.
Evan Harper

Cevapların hiçbirini göremiyorum. Kullanıcı belirteci alıştırmasının amacı, kullanıcının e-posta adresinin çalıştığını kanıtlamak olmalıdır. Bu nokta olmasaydı, belirteci basitçe saklamak çok daha basit olurdu.
emory

2
Bu oldukça korkunç. Eğer böyle bir kartı kesinlikle doldurmak gerekiyorsa, kütüphaneyi kullanarak ayrı bir çalıştırılabilir hale getirebilir ve kartınızı stdin'e aktarabilirsiniz. Ancak çağıran çalıştırılabilir dosya kodunu çalmak için bir hayır-hayır.
GrandmasterB

Yanıtlar:


78

Genel bir kılavuz olarak, kütüphanelerin çevre ile tamamen bağlantısı kesilmelidir. Bu, standart akışlarda, belirli dosyalarda işlem yapmamaları gerektiği veya kullanıldığı ortam veya bağlamla ilgili herhangi bir beklentileri olmadığı anlamına gelir.

Tabii ki, bu kuralın istisnaları var, ama bunun için çok iyi bir sebep olmalı. Kullanma durumunda, stdinherhangi bir sebep bulamıyorum (kütüphaneniz gerçekte std::cinC ++ 'dan olduğu gibi stdin'den okumak için rutinler sağlamazsa ). Ayrıca, G / Ç akışlarını bir parametreden kodlamalarını sağlamak yerine almak, yapmamaya değmeyecek kadar esneklik sağlar.


36
Bunun istisnası, belirli bir ortamla etkileşimde bulunma hedefi olan bir kütüphanedir. O zaman bile, çevrenin detayları soyutlanmalıdır. Örneğin, bir grafik sürücüsünün PCIe veriyolu ile iletişim kurması gerekir, ancak veri yolu kimliği yapılandırma yoluyla sağlanmalıdır.

Bu düşündüğüm bir istisna türü: fikrim ncurses'e daha yakındı - genellikle bir metin ortamı kullanıcı arayüzü kütüphanesi. Amacı kullanıcı girişini okumak ve kullanıcı çıktısını sağlamaksa, bu iyi bir nedendir.
SF.

5
@SF. Ncurses gibi bir kütüphane bile 0 ve 1 kullanımlarını kodlamak yerine, argüman olarak bir çift dosya tanımlayıcısı almalıdır. Stdin ve stdout'un yönlendirilebileceği bir program yazmak isteyebilir ve bunun yerine /dev/ttyiletişim kurmak için açmak isteyebilirsiniz . kullanıcı. Program bir terminal olmadan da başlatılabilir ve kendi terminalini kullanarak açılabilir xterm -S.
kasperd

3
@ kasperd: En iyi yaklaşım, makul varsayılanlar ve bunları geçersiz kılma yeteneği sağlamaktır.
SF.

1
Bu özel durumda, girdi olarak bir akım talep etmek için hiçbir neden göremiyorum . Neden belirteci sadece parametre olarak kabul etmiyorsunuz ?
jpmc26

16

Bunun mutlaka bir anti-patern değil, sadece kötü tasarlanmış bir kütüphane olduğunu düşünürdüm. Girdiyi doğrudan iletilebilecek bir yöntem parametresi olarak bir dize istemek önemsiz olmalıdır.

Bu kullanıma uymuyorsa, bir yöntem parametresi bir akış olabilir, STDIN bu metoda iletilir.

Bu, bu kullanıma uymuyorsa, kütüphane yeterince esnek değildir.


4

Belki de kütüphanenizde, girişi her yerden okuyabilecek ve kullanıcı tarafından sağlanan bir fonksiyon için bir geri arama ayarlama yeteneğine sahip olmayı düşünün ve ardından uygun değeri kütüphanenin hangi fonksiyonunu kullanıyorsa geri getirin.


1

Stdin'den okursa, stdin'in program düzeyinde sahipliğini almak istediği anlamına gelir. Muhtemelen kullanımı nasıl kullandıklarına dair stdin, daha az spesifik protokolden okuyan başka bir kütüphane ile uyumlu değildir. En azından kendi kişisel sözlüğümde bu, kütüphaneyi pahalı bir tradeoff olan bir çerçeve yapacaktır .

Ancak bu durumda, kütüphane muhtemelen bir girdi dosyası tanımlayıcısı almalıdır.


0

@ Paul92 tarafından verilen cevap genel bir tartışmadır, ancak bunun için olası bir temiz ( çözüm ) çözüm önermek istiyorum :

Bir kitaplık, bu kodun herhangi bir çalışma zamanı ortamına uyarlanabilir olması gerekir, bu nedenle gerçekten STDINçok önemli bir veri biti isteyemezsiniz . Birincisi, kütüphanenizin kullanıcılarının bir takım sebeplerden dolayı kullanmaları mümkün olmayabilir. Bunun yerine , belirtecin nasıl alınacağını özelleştirmek için bir çeşit strateji deseni kullanmak isteyebilirsiniz .

Python'da, muhtemelen en iyi seçenek, işlev belirteç olarak belirteç alma stratejisine geçmektir. Bunun gibi bir şey:

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

Böyle düşün. İstediğiniz belirteç, kütüphane işlevinin bir argümanıdır. Belirteç değeri, arama sitesinde statik olarak bilinmediğinden, değeri argüman olarak isteyemezsiniz. Bunun yerine, arayan kişi arandığında belirteci sağlamaktan sorumlu olacak bir işlev sağlamalıdır.

Belirtecin tam mekaniğini sağlamadaki tüm sorumluluk şimdi kütüphane işlevinden dışlanmıştır. Fonksiyonun tüketicisi şimdi belirteci çalışma zamanında mevcut olan herhangi bir yöntemle elde etmekten sorumludur. STDIN'e sorabilir, ancak bir posta ağ geçidi olarak da hareket edebilir, mesajın gelen kutusuna gelmesini bekleyebilir, okuyabilir, belirteci çıkarabilir ve işlemi tamamen otomatikleştirebilirsiniz. Bir GUI iletişim kutusu veya web tabanlı bir form olabilir. Gerçekten her şey - tüm seçenekler şimdi kütüphane tüketicisinin elinde.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.