Global istek bağlamı - anti-desen?


12

Bugün bir meslektaşımla Python web çerçeveleri ve onlar hakkındaki izlenimlerimiz hakkında konuşuyordum. Ona küresel bir isteği olan Flask'ın kötü koktuğunu ve bir anti-desen olduğunu düşündüğümü söyledim.

Docs istek içeriği hakkında ki:

Bunun aksine, istek işleme sırasında birkaç kural daha vardır:

  • bir istek etkinken, bağlam yerel nesneleri (flask.request ve diğerleri) geçerli isteği gösterir.
  • herhangi bir kod herhangi bir zamanda bu nesneleri tutabilir.

Bu tasarım kararının arkasındaki fikri anladığımı düşünüyorum - uygulamayı kolaylaştırmak için. İş Parçacığı Yerellerinde olduğu gibi sadece bir uzlaşma :

Evet, iş parçacığı yerlilerinin kullanılması o kadar parlak bir fikir değildir. İş parçacığı kavramına dayanmayan ve büyük uygulamaların bakımını zorlaştıran sunucular için sorunlara neden olurlar. Ancak Flask sadece büyük uygulamalar veya asenkron sunucular için tasarlanmamıştır. Flask, geleneksel bir web uygulaması yazmayı hızlı ve kolay hale getirmek istiyor.

Mevcut istek bilgileriyle global bir nesne yamalamak bir anti-desen midir?

Buna inanıyorum, çünkü statik kod analizörünün küresel bir durum görünümünde olmasına rağmen, öyle değil. Ve ben bir programcı olarak belgeleri dikkatlice okumadan nasıl çalıştığını anlamayacağım . Bunun testler üzerinde sonuçları var .

İsteği görüşlere argüman olarak iletmek iyi bir uygulama değil mi? Bence daha okunabilir, açık ve hata ayıklaması daha kolay. Ve küresel devletten kaçınır.


2
Böyle bir antipatternerin spesifik olumsuz etkilerinin ne olabileceğini gerçekten belirtmediniz. Olgusal temeli olmayan kapsamlı genellere güvenmiyorum.
Robert Harvey

2
İyi soru, ama ne yazık ki pek çok kaliteli cevap yok
sleepycal

Yanıtlar:


4

Birçok web çerçevesi aynı yapıya sahiptir: küresel bir istek. Bir anlamda yapılması gereken doğru şey, çünkü hey, bir seferde sadece bir istek var.

Peki, isteği parametre olarak iletmenin herhangi bir anlamı var mı? Hayır. İstek istektir ve parametreler farklı zamanlarda farklı şeyleri iletmek içindir.

Gerçek daha büyük bir uygulamanın alt seviyelerini dikkate almak başlar başlamaz sorun geliyor. Global bir istekte, global olarak talebe erişen her yere kod yazma cazibesi vardır. Bu çok kötü bir şey . Kodun farklı bölümleri arasında bağlantı üretir, bir şeyleri değiştirmeyi zorlaştırır ve bir şeyleri test etmeyi zorlaştırır.

Cevabım şudur: küresel talebi devam ettirin ve onunla yaşayın. Bununla birlikte, tek bir modül veya fonksiyonun tüm talebe ihtiyaç duymadığı durumlarda, sadece ihtiyaç duyduğu verileri bir parametre olarak iletin. Sadece yönlendireni, url'yi veya komut kuyruğunu ve ihtiyacınız olan bitleri işlevlerinize iletin. Bu, kodu modüler tutmaya, kuplajı azaltmaya ve test edilebilirliği geliştirmeye yardımcı olacaktır.

Küçük programlar için bu çok önemli değil, ancak büyük programlar için bu gerçek bir cankurtaran olabilir.


3

(Cesur olacağım ve bunu bir cevap yapacağım, ancak bazı indirimler alabilirim.)

Şişe bir mikro-çerçevedir; fırfırlardan vazgeçerken basitlikten faydalanırsınız. Bağırsak seviyesinde sana katılıyorum, bana ihtiyacım olan çok iş parçacığını vermek için bir dükkanda flask + gunicorn kullandığımı biliyorum. Gerçekten iyi çalıştı . Betiğin her bir örneği bir istek (yani bir iş parçacığı) yerine getirdi ve gunicorn birden fazla iş parçacığı arasında "yelpazeyi" işledi. Bu harikaydı.

Böylece, hissettiğiniz algılanan dezavantaj - birden çok iş parçacığının küresel durum için mücadele edebileceği - sadece sorun değil, çünkü iş parçacığı başına bir komut dosyasıdır.

(İşte başım belaya girebilir) Python dünyasında iş parçacığı ve eşzamanlılık sadece farklıdır ve eğer ona bir Java çerçevesi ile gelirseniz, onu sıkmak zordur. Deneyimim, aldığım eşzamanlılık sorunları Java ile verilen veya uygulama kabı tarafından saydam olarak işlenen Python'daki yüzeye çok daha yakındır.

Bir iş parçacığının komut dosyamın bir çağrışımını ele alması garipti, ama aynı anda bir kutu üzerinde birkaç düzine çalıştıktan sonra daha iyi hissettim.


4
İplik güvenliği ve benzeri konulardan endişe etmiyorum. Bu durumlarda Flask'ın iyi çalıştığına inanıyorum. Benim sorum uygulama tasarımı ve mimarisi ile ilgili. İsteği görüşlere argüman olarak iletmek iyi bir uygulama değil mi? Bence daha okunabilir, açık ve hata ayıklaması daha kolay.
warvariuc

2

Python'da printstandart çıktıya baskı yapan komuta (v3'ten beri fonksiyon) sahipsiniz . STDOUT'a yazdırmak istediğinizi açıkça belirtmezsiniz - bu, sahne arkasında örtülü olarak sizin için yapılır.

Dolaylı olarak. Python'da. Ve kimsenin bununla bir sorunu yok. Neden?

printPython dilinin bir parçasıdır ve Python'da programlama gereksinimlerinden biri ... Python'u tanımaktır. Python'u tanıyorsanız, bunun printSTDOUT'u hedeflediğini biliyorsunuz . Orada sürpriz yok.

Python - bir dil olarak - kendi kuralını tanımlayabilir ve programcıların bunlardan haberdar olduğunu varsayabilir.

Çerçeveler de bu ayrıcalığa sahiptir - bu bir çerçeve ile kütüphane arasındaki temel farklardan biridir. Kütüphaneyi kullanabilmek için öğrenmeniz gerekmiyor - sadece API'nın ihtiyacınız olan kısmını bulmanız ve dilin (veya çerçevenin) kurallarına uyduğunu varsayın. Bu yüzden işe alım yapanların GSON veya Apache Commons'ta bilgi sahibi insanları aradığını görmüyorsunuz. Ancak, JQuery veya Ruby on Rails veya ASP.NET MVC ile deneyime sahip insanları arayan işe alım görevlileri görüyorsunuz - bunlar, öğrenmeniz ve farkında olmanız gereken kendi sözleşmelerini tanımlayan çerçevelerdir.

Flask, bir çerçeve olarak, bağlamı yerel bir küresel ortamda depolamak için bir kural tanımlayabilir - ve kimseyi şaşırtmamalı, bu yüzden bir anti-desen değil.


2
"Stdout" un dosya tanımlayıcı tarafından işaret edildiği anlamına gelir sys.stdout. Bunu değiştirirseniz, baskı başka bir yere gider.
Phoshi

1
Ayrıca, Python3'te işlev görmek için >>işleci kullanarak veya filebağımsız değişkeni kullanarak çıkış akışını geçersiz kılabilirsiniz print. Yani, sys.stdoutgeçersiz kılınabilecek varsayılan bir değerdir.
warvariuc
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.