Uyarı! C ++ programcısı, istisna işlemenin kesinlikle başka bir dil ile ilgili bir soruyu cevaplamaya çalışırken nasıl yapılacağına dair muhtemelen farklı fikirlerle geliyor!
Bu fikir verildiğinde:
Örneğin, HTTP isteğini yerine getiren ve alınan verileri döndüren bir kaynağa sahip olduğumuzu düşünün. Ve ServiceTemporaryUnavailable veya RateLimitExceeded gibi hatalar yerine, tüketiciye sadece talebi yeniden denemesi ve belirli bir arızayı önemsememesi gerektiğini belirten bir RetryableError oluşturacağız.
... önerebileceğim bir şey, kodunuzun genelliğini bozabilecek veya istisnalar için çok sayıda "çeviri noktası" gerektirebilecek şekilde yanıt vermek için bir hata bildirme eylemleriyle ilgili endişeleri karıştırıyor olabilirsiniz. .
Örneğin, bir dosyayı yüklemeyi içeren bir işlemi modellediğimde, bunun birkaç nedeni olabilir. Belki de dosyanın yüklenmesi kullanıcının makinesinde olmayan bir eklentinin yüklenmesini içerir. Belki de dosya bozulmuş ve ayrıştırılırken bir hatayla karşılaştık.
Ne olursa olsun, eylemin seyrini kullanıcıya ne olduğunu bildirmek ve ona ne yapmak istediğini sormak olduğunu varsayalım ("tekrar dene, başka bir dosya yükle, iptal et").
Atıcı ve Avcı
Bu eylem, bu durumda ne tür bir hatayla karşılaştığımızdan bağımsız olarak uygulanır. Genel olarak bir ayrıştırma hatası fikrine gömülmez, bir eklentiyi yükleyememe genel fikrine gömülü değildir. Bir dosya yüklemenin kesin bağlamı (bir dosya yükleme ve başarısızlık kombinasyonu) sırasında bu tür hatalarla karşılaşma fikrine gömülüdür. Yani tipik olarak, kabaca konuşarak, catcher's
atılan bir istisna (örneğin: kullanıcıya seçeneklerle sorma) yanıt olarak eylemin seyrini belirleme sorumluluğu olarak görüyorum thrower's
.
Başka bir deyişle, throw
istisnaları olan siteler , özellikle de atanan işlevler genel olarak uygulanabilirse, bu tür bağlamsal bilgilerden yoksundur. Bu bilgilere sahip olduklarında tamamen dejenere olmuş bir bağlamda bile, throw
siteye gömerek kurtarma davranışı açısından kendinizi köşeye sıkıştırırsınız . Bir catch
eylemin seyrini belirlemek için genellikle en fazla bilgiye sahip olan sitelerdir ve bu işlemin söz konusu işlem için değişmesi gerekip gerekmediğini değiştirmek için size merkezi bir yer verir.
Artık neyin yanlış olduğunu bildirmekle kalmayıp ne yapacağınızı belirlemeye çalışırken istisnalar atmaya başladığınızda, bu kodunuzun genelliğini ve esnekliğini bozabilir. Ayrıştırma hatası her zaman bu tür bir isteme yol açmamalıdır, bu tür bir istisnanın atıldığı bağlama göre değişir (atıldığı işlem).
Kör Atıcı
Sadece genel olarak, istisna işleme tasarımının çoğu genellikle kör bir atıcı fikri etrafında döner. İstisnanın nasıl yakalanacağını veya nerede yakalanacağını bilmiyor. Aynı durum, manuel hata yayılımı kullanan eski hata kurtarma biçimleri için bile geçerlidir. Hatalarla karşılaşan siteler, kullanıcının bir işlem biçimini içermez, yalnızca ne tür bir hatayla karşılaşıldığını bildirmek için yalnızca minimum bilgileri yerleştirir.
Ters Sorumluluklar ve Yakalayıcının Genelleştirilmesi
Bunu daha dikkatli bir şekilde düşünürken, bunun bir cazibe olabileceği bir kod tabanı hayal etmeye çalışıyordum. Hayal gücüm (muhtemelen yanlış), ekibinizin hala burada "tüketici" rolünü oynadığı ve arama kodunun çoğunu uyguladığı. Belki de try
hepsi aynı hata kümelerine girebilecek birçok farklı işleminiz (çok sayıda blok) var ve hepsi tasarım açısından bakıldığında tek tip bir kurtarma eylemine yol açmalı.
Lightness Races in Orbit's
İnce cevabın akıllıca tavsiyelerini göz önünde bulundurarak (gerçekten gelişmiş bir kütüphane odaklı zihniyetten geldiğini düşünüyorum), yine de "ne yapmalı" istisnaları atmak için cazip olabilirsiniz, sadece işlem kurtarma sitesine daha yakın.
Buradan, aslında "ne yapmalı" endişelerini merkezileştiren, ancak yine de yakalama bağlamında, aracı, ortak bir işlem gerçekleştirme sitesi bulmak mümkün olabilir.
Bu, yalnızca bu dış işlemlerin tümünün kullandığı bir tür genel işlev tasarlayabiliyorsanız (ör: çağrılacak başka bir işlevi giren bir işlev veya karmaşık alıcı siteyi yapan bu aracı işlem sitesini modelleyen geçersiz kılınabilen davranışa sahip soyut bir işlem tabanı sınıfı tasarlayabiliyorsanız geçerlidir. ).
Yine de, çeşitli olası hatalara yanıt olarak ve hala atmak yerine yakalama bağlamında kullanıcı hareket tarzını merkezileştirmekten sorumlu olabilir. Basit bir örnek (Python-ish sözde kodu, ve ben en ufak bir tecrübeli Python geliştiricisi değilim, bu yüzden bu konuda daha deyimsel bir yol olabilir):
def general_catcher(task):
try:
task()
except SomeError1:
# do some uniformly-designed recovery stuff here
except SomeError2:
# do some other uniformly-designed recovery stuff here
...
Umarım daha iyi bir isimle general_catcher
]. Bu örnekte, hangi görevi gerçekleştireceğinizi içeren, ancak ilgilendiğiniz tüm istisna türleri için genelleştirilmiş / birleştirilmiş yakalama davranışından yararlanan bir işlevi geçirebilir ve "ne yapmalı" bölümünü genişletmeye veya değiştirmeye devam edebilirsiniz. bu merkezi konumdan ve yine de catch
bunun genellikle teşvik edildiği bir bağlamda hoşunuza gidiyor . Hepsinden iyisi, fırlatma alanlarının kendilerini "ne yapmalı" ("kör atıcı" kavramını koruyarak) ile ilişkilendirmekten alıkoyabiliriz.
Burada bu önerilerin hiçbirini yararlı bulmazsanız ve yine de "ne yapmalı" istisnaları atmak için güçlü bir cazibe varsa, esas olarak bunun en azından çok anti-deyimsel olduğunun ve genelleştirilmiş bir zihniyetin potansiyel olarak cesaret kırıcı olduğunun farkında olun.