İstisnaların işlenmesi neden kötü?


93

Google'ın Go dilinin bir tasarım seçeneği olarak istisnası yoktur ve Linux'un şöhreti Linus istisnalar saçmalığı olarak adlandırmıştır. Neden?


2
ZeroMQ'nun yaratıcısı, C ++ ile yazmanın nasıl bir hata olduğunu düşündüğünü yazıyor (çoğunlukla hata işleme nedeniyle) 250bpm.com/blog:4
serbaut

Go'nun istisnaları olmayabilir, ancak "telafi edebileceğiniz" (ertelenmiş ifadeler hala yürütülürken) ve yerel olmayan kontrol akışı sağlayan "paniklere" sahiptir ...
Kerrek SB

İşte güzel bir makale lighterra.com/papers/exceptionsharmful (İstisna İşleme Zararlı
Kabul Ediliyor

Afaics, istisnalar Go'da önemli bir standart şablonla simüle edilebilir , ancak bu nokta bir sözdizimi şekerinden kopyalamak için standart metni manuel olarak yazmaktan daha anlamlı olabilir.
Shelby Moore III

Yanıtlar:


83

İstisnalar, atılan bir istisnanın değişmezleri kıracağı ve nesneleri tutarsız bir durumda bırakacağı durumlarda kod yazmayı gerçekten kolaylaştırır. Esasen, yaptığınız her ifadenin çoğunun potansiyel olarak atabileceğini ve bunu doğru şekilde ele alabileceğini hatırlamaya zorlar. Bunu yapmak aldatıcı ve mantıksız olabilir.

Bunun gibi bir şeyi basit bir örnek olarak düşünün:

class Frobber
{
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:
    void Frob()
    {
        m_NumberOfFrobs++;

        m_FrobManager.HandleFrob(new FrobObject());
    }
};

Varsayarsak FrobManagerolacak doğru, bu bakışlar OK? Ya da belki ... sonra hayal edin ya değil ya bir istisna atar. Bu örnekte, artış değeri geri alınmaz. Bu nedenle, bu örneğini kullanan herkesin muhtemelen bozuk bir nesnesi olacaktır.deleteFrobObjectFrobManager::HandleFrob()operator newm_NumberOfFrobsFrobber

Bu örnek aptalca görünebilir (tamam, bir tane oluşturmak için kendimi biraz esnetmek zorunda kaldım :-)), ancak çıkarım, eğer bir programcı sürekli olarak istisnaları düşünmüyorsa ve durumun her permütasyonunun yuvarlanmasını sağlamaktır. ne zaman atış olursa, bu şekilde başınız belaya giriyor.

Örnek olarak, muteksleri düşündüğünüz gibi düşünebilirsiniz. Kritik bir bölümün içinde, veri yapılarının bozuk olmadığından ve diğer iş parçacıklarının ara değerlerinizi göremediğinden emin olmak için birkaç ifadeye güvenirsiniz. Bu ifadelerden herhangi biri rastgele bir şekilde çalışmazsa, acı dolu bir dünyaya girersiniz. Şimdi kilitleri ve eşzamanlılığı ortadan kaldırın ve her yöntemi bunun gibi düşünün. İsterseniz, her yöntemi nesne durumundaki permütasyonların bir işlemi olarak düşünün. Yöntem çağrınızın başlangıcında, nesne temiz durumda olmalı ve sonunda da temiz bir durum olmalıdır. Arada, değişken fooile tutarsız olabilirbar, ancak kodunuz sonunda bunu düzeltir. İstisnaların anlamı, ifadelerinizden herhangi birinin herhangi bir zamanda sizi rahatsız edebilmesidir. Her bir yöntemde, bunu düzeltmek ve bu olduğunda geri almak veya işlemlerinizi, nesnenin durumunu etkilemeyecek şekilde sıralamak için sorumluluk size aittir. Yanlış anlarsanız (ve bu tür bir hatayı yapmak kolaysa), arayan kişi ara değerlerinizi görmeye başlar.

C ++ programcılarının bu soruna nihai çözüm olarak bahsetmeyi sevdikleri RAII gibi yöntemler, buna karşı korunmak için uzun bir yol kat ediyor. Ama sihirli değnek değiller. Kaynakları bir atışta serbest bırakmanızı sağlar, ancak sizi nesne durumundaki bozulma ve ara değerleri gören arayanlar hakkında düşünme zorunluluğundan kurtarmaz. Bu nedenle, birçok insan için, istisnasız bir kodlama stiline göre söylemek daha kolay . Yazdığınız kod türünü kısıtlarsanız, bu hataları ortaya çıkarmak daha zordur. Eğer yapmazsanız, hata yapmak oldukça kolaydır.

C ++ 'ta istisnai güvenli kodlama hakkında tüm kitaplar yazılmıştır. Pek çok uzman yanlış anladı. Gerçekten bu kadar karmaşıksa ve çok fazla nüansı varsa, bu özelliği görmezden gelmeniz gerektiğine dair iyi bir işaret olabilir. :-)


9
İlginç cevap, ancak programlama deneyimimdeki hiçbir şeyi yansıtmıyor. Bu yüzden ya kültüre özgü (belki Java ya da C ++ 'da Python'dan daha fazla bir problem) ya da alana özgü olduğunu tahmin ediyorum.
ddaa

42
Bir dene-yakala kalıbı kullanılarak yönetilen bir dilde yazılan istisnalar, düzgün yazıldıkları takdirde asla geçersiz durum bırakmamalıdır; Nihai bloğun yürütülmesi garanti edildiğinden, nesneler burada serbest bırakılabilir. Geri kalanı kapsam dışı değişkenler ve çöp toplama ile halledilmelidir.
Robert Harvey

7
@ddaa Sorun Python'da kesinlikle mümkündür. Sonuç tipik olarak yeniden üretilmesi zor bir hatadır. Belki de özellikle titiz veya şanslıydınız. Ama sonra, zayıf EH'den kaynaklanan en yaygın hatanın bellek sızıntısı olduğu C ++ 'da bir sorun olduğu konusunda haklısınız. Sızıntıların en ciddi sorun olmadığını vurgulamaya çalıştım. @Robert GC bellek sızıntılarını azaltacaktır, ancak yönetilen kodun sizi programcı hatasından kurtaracağından emin değilim. Özellikle, birisi kendi dillerinde bir sorun olduğunu düşünmediği için istisna güvenliğine dikkat etmiyorsa, bu harika bir işaret değil.
asveikau

4
@lzprgmr kesinlikle vardır: istisnalar diff ile başa çıkmanıza izin verir. diff'deki hata türleri. koddaki yerler. Bir bağlantı hatasıyla başa çıkmak için yeniden bağlantı gerekebilir, ancak derinlemesine iç içe geçmiş bir işlevin ortasında değil. Bunu bağlantı yöneticisine falan uçurmak istiyorsun. Daha sonra dönüş değerleriyle uğraşmak sizi her bir çağrıda hataları kontrol etmeye ve bunu manuel olarak balonlamaya zorlar (örneğin bir bağlantı sıfırlama hatası durumunda). Ayrıca, dönüş değerleri iç içe geçmiş çağrılarda birikir: func3 -1 döndürebilir, func2 çağrıları func3, hatalarında -2, func3'ler için -1, vb.
abourget

4
Olumsuz oy veriyordum, ama bunu tersine çevirdim çünkü istisnaların hor görülmesinin bir nedeni bu. Ancak bence neredeyse her yöntem veya kod parçası başarısız olabilir. Her hata koşulunu, kendisi için bir dönüş değeri sunarak işleyemezsiniz. Hatayla ilgili bilgileri kaybedeceksiniz. Her bir ifadeyi kontrol ederek ve temizlemeyi yaparak her şeyi güzel bir şekilde senkronize edebileceğinizi düşünmek, çok kıvrımlı koda yol açar - birden fazla ifadede bir hata yakalamak ve GC'lenmemiş bir veya iki kaynağı temizlemek çok daha temizdir.
Maarten Bodewes

50

Go'nun istisnalara sahip olmamasının nedeni Go dili tasarımı SSS bölümünde açıklanmıştır:

İstisnalar benzer bir hikaye. İstisnalar için bir dizi tasarım önerilmiştir, ancak her biri dile ve çalışma süresine önemli ölçüde karmaşıklık katmaktadır. Doğası gereği, istisnalar işlevleri ve hatta belki de gorutinleri kapsar; geniş kapsamlı çıkarımları vardır. Ayrıca kütüphaneler üzerinde yaratacağı etki konusunda da endişeler var. Tanımı gereği istisnaidirler, ancak onları destekleyen diğer dillerle ilgili deneyimler, kitaplık ve arayüz özellikleri üzerinde derin etkileri olduğunu gösterir. Genel hataları her programcının telafi etmesini gerektiren özel kontrol akışına dönüşmeye teşvik etmeden gerçekten istisnai olmalarına izin veren bir tasarım bulmak güzel olurdu.

Jenerik ilaçlar gibi istisnalar da açık bir sorun olmaya devam ediyor.

Başka bir deyişle, Go'daki istisnaları tatmin edici buldukları bir şekilde nasıl destekleyeceklerini henüz çözemediler. Onlar İstisnalar kötü olduğunu söylemiyoruz se başına ;

GÜNCELLEME - Mayıs 2012

Go tasarımcıları şimdi çitin üzerinden aşağı indi. SSS'leri şimdi şunu söylüyor:

Try-catch-nihayet deyiminde olduğu gibi bir kontrol yapısına istisnaların birleştirilmesinin kıvrımlı kodla sonuçlandığına inanıyoruz. Ayrıca, programcıları, bir dosyayı açamama gibi çok fazla sıradan hatayı istisnai olarak etiketlemeye teşvik etme eğilimindedir.

Go farklı bir yaklaşım sergiliyor. Düz hata işleme için Go'nun çoklu değer dönüşleri, dönüş değerini aşırı yüklemeden bir hatayı bildirmeyi kolaylaştırır. Go'nun diğer özellikleriyle birlikte kanonik bir hata türü, hata işlemeyi keyifli hale getirir, ancak diğer dillerdekinden oldukça farklıdır.

Go ayrıca, gerçekten istisnai koşullardan sinyal almak ve kurtarmak için birkaç yerleşik işleve sahiptir. Kurtarma mekanizması, yalnızca bir hatadan sonra yıkılan bir işlevin durumunun bir parçası olarak yürütülür; bu, felaketi ele almak için yeterlidir, ancak ekstra kontrol yapıları gerektirmez ve iyi kullanıldığında temiz hata işleme koduyla sonuçlanabilir.

Ayrıntılar için Defer, Panic ve Recover makalesine bakın.

Dolayısıyla kısa cevap, bunu çok değerli getiri kullanarak farklı şekilde yapabilecekleridir. (Ve yine de bir tür istisna işleme şekli var.)


... ve Linux'un ünlü Linus'u istisnalar saçmalığı olarak adlandırdı.

Linus'un neden istisnaların saçmalık olduğunu düşündüğünü bilmek istiyorsanız, en iyisi konuyla ilgili yazılarına bakmaktır. Şimdiye kadar izlediğim tek şey , C ++ üzerindeki birkaç e-postaya gömülü olan bu alıntı :

"Tüm C ++ istisna işleme olayı temelden bozuldu. Özellikle çekirdekler için bozuk."

Özellikle C ++ istisnalarından bahsettiğini ve genel olarak istisnalardan bahsetmediğini fark edeceksiniz. (Ve C ++ istisnalarının , doğru şekilde kullanılmalarını zorlaştıran bazı sorunları var.)

Benim sonucum, Linus'un istisnaları (genel olarak) "saçmalık" olarak adlandırmadığıdır!


30
Bilgileri SSS bölümüne ekleyerek gizlemelerinden nefret ediyorum. :)
brian d foy

7
Linus'un bu e-postayı "C ++ korkunç bir dil" ile başlattığını unutmayın. ve hem C ++ 'dan hem de onu programlamayı seçen insanlardan ne kadar nefret ettiği hakkında söylenmeye devam ediyor. Sonuç olarak, C ++ 'nın istisnaları hakkındaki görüşünün, C ++' ya yönelik biraz önyargılı görüşü göz önüne alındığında güvenilir olarak kabul edilebileceğini düşünmüyorum.
Pharap

1
@ Hi-Angel - Alıntı yaptığım metinde söylediği gibi: "Düz hata işleme için, Go'nun çoklu değer dönüşleri, dönüş değerini aşırı yüklemeden bir hatayı bildirmeyi kolaylaştırır." . İlişkisi budur. Her iki durumda da, Go tasarımcılarının mantığından alıntı yapıyorum. Tartışmak istiyorsanız, >> onlarla << tartışın.
Stephen C

1
@ Hi-Angel - Bu paragrafları ben yazmadım. Ben sadece alıntı yaptım. Eğer onlarla bir sorununuz varsa, muhtemelen bunu yazarlarla görüşmelisiniz. Teoride, bağlam olarak Go dili hakkında bir eğitim sunabilirdim. Ancak dürüst olmak gerekirse, Go terminolojisini anlamayan kişiler, tüm bunların ne anlama geldiğini öğrenmek için Go web sitesini ziyaret edebilir.
Stephen C

1
".. karmaşık kodla sonuçlanır" Uzun zaman önce birçok dizgi işlemi ile C programı yazmıştım. Her yöntem bellek ayırma ve ardından ayırmanın başarılı olup olmadığını kontrol etmekti. Kodun çoğunluğunun sadece tahsisleri kontrol ettiği görüldü. Kıvrılmış değil mi? İstisnalar dışında C ++ benim için büyük bir kurtarma oldu.
robsosno

30

İstisnalar kendi başına kötü değildir, ancak çok olacaklarını biliyorsanız, performans açısından pahalı olabilirler.

Temel kural, istisnaların istisnai koşulları işaretlemesi ve bunları program akışının kontrolü için kullanmamanız gerektiğidir.


9
@Robert: "Bunları program akışının kontrolü için kullanmamalısın", bu şekilde düşünmedim, benim için yeni bir bakış açısı: P +1
okw

2
Aynı zamanda gerçekten dile de bağlıdır. Örneğin Java ile programlama yapıyorsanız istisnalardan kaçınmak zordur.
Charles Salvia

2
@Charles: Bence önemli olan, bir hatayı, yanlış yapılandırılmış sistemi veya mantıksız girdileri gösteren durumlarda istisnaların uygun olmasıdır. Java kitaplık istisnalarının çoğu "normal iş akışı" kodunda önlenebilir.
Artelius

6
çok pahalı olmaları gerekmez. örneğin, sıfır yürütme süresine mal olan bir "dene" uygulayabilir ve yığında gördüğü arayan adreslerine göre bir tabloda istisna işleyicileri "atabilir" ... kullanım istisnaları hiçbir şekilde performansla ilgili değildir.
asveikau

Yeniden yayımlandı; Soru, genel olarak istisnaları kullanmayı veya istisnaları hiç kullanmamayı açıkça ima eder (bunlar saçmadır veya dilde bile değildir). Cevabınız yalnızca program kontrol akışı için kullanıldığında istisnaların performans için neden kötü olduğunu gösterir.
Maarten Bodewes

27

"Yalnızca istisnai durumlarda istisnalar atın" fikrine katılmıyorum. Genel olarak doğru olsa da yanıltıcıdır. İstisnalar hata içindir durumları içindir (yürütme hataları).

Bağımsız olarak kullanmak dilin, bir kopyasını almak Çerçeve Tasarım Rehberi Yeniden kullanılabilir NET Kütüphaneleri (2nd Edition) için Sözleşmeleri, Deyimler ve Kalıpları:. İstisna atma ile ilgili bölüm emsalsizdir. İlk baskıdan bazı alıntılar (ikincisi işimde):

  • YAPMA hata kodlarını döndürür.
  • Hata kodları kolayca göz ardı edilebilir ve çoğu zaman öyledir.
  • İstisnalar, çerçevelerdeki hataları rapor etmenin birincil yoludur.
  • İyi bir temel kural, bir yöntem adından da anlaşılacağı gibi yapmazsa, bir istisnayla sonuçlanan yöntem düzeyinde bir başarısızlık olarak kabul edilmesi gerektiğidir.
  • Mümkünse, normal kontrol akışı için istisnalar KULLANMAYIN .

İstisnaların yararları (API tutarlılığı, hata işleme kodunun konumu seçimi, geliştirilmiş sağlamlık, vb.) Hakkında not sayfaları vardır. Performansla ilgili birkaç model içeren bir bölüm vardır (Tester-Doer, Try-Parse).

İstisnalar ve istisna yönetimi fena değil . Diğer herhangi bir özellik gibi, kötüye kullanılabilirler.


4
Buna katılmamalıyım. İstisnalara karşı değilim ve bu kitap mutlaka sahip olunması gereken bir kitap, ancak .NET geliştirme ve C # yönünde önyargılı.

3
Bunun eski olduğunu biliyorum, sadece .NET türü ile * nix türü arasında genel bir stil uyuşmazlığı olacağı şeklinde yorum yapmak istedim. Linux geliştiricisi olarak kullandığım tüm kitaplıklar dönüş kodları kullanıyor ve okuduğum * nix stil kılavuzları (örneğin şirketim ve Google'ınki gibi) sadece "istisnalar yapmıyoruz" diyor. Sadece ilginç olduğunu düşün.
jarvisteve

1
Çerçeveler, istisnaları son kullanıcı uygulamalarından farklı şekilde ele almalıdır. Tüketici uygulamalarının yaptığı gibi, çerçevelerin istisna atmaktan başka hatalarla başa çıkmanın bir yolu yoktur.
0x6C38

12

Golang açısından bakıldığında, istisna işlemeye sahip olmamanın derleme sürecini basit ve güvenli tuttuğunu tahmin ediyorum.

Linus'un bakış açısından, çekirdek kodunun TÜM köşe durumlarla ilgili olduğunu anlıyorum. Bu nedenle istisnaları reddetmek mantıklıdır.

Mevcut görevi yere bırakmanın sorun olmadığı ve ortak durum kodunun hata işlemeden daha önemli olduğu durumlarda kodda istisnalar anlamlıdır. Ancak derleyiciden kod üretmeyi gerektirirler.

Örneğin, web ve masaüstü uygulama kodu gibi çoğu üst düzey, kullanıcıya dönük kodda iyidirler.


Ancak çekirdek kodu için doğru olan, uzun süre çalışan yerel sunucu işlemleri için de geçerlidir.
Lothar

11

İstisnalar kendi içlerinde "kötü" değildir, bazen kötü olma eğiliminde olan istisnaların ele alınma şeklidir. Bu sorunlardan bazılarının hafifletilmesine yardımcı olmak için istisnaları ele alırken uygulanabilecek birkaç kılavuz vardır. Bunlardan bazıları şunları içerir (ancak bunlarla sınırlı değildir):

  1. Program akışını kontrol etmek için istisnalar kullanmayın - yani mantığın akışını değiştirmek için "catch" ifadelerine güvenmeyin. Bu sadece mantık etrafındaki çeşitli ayrıntıları gizleme eğiliminde olmakla kalmaz, aynı zamanda düşük performansa da yol açabilir.
  2. Döndürülen bir "durum" daha mantıklı olduğunda bir işlev içinden istisnalar atmayın - yalnızca istisnai bir durumda istisnalar atın. İstisnalar oluşturmak pahalı ve yoğun performans gerektiren bir işlemdir. Örneğin, bir dosyayı açmak için bir yöntem çağırırsanız ve bu dosya yoksa, bir "FileNotFound" istisnası atın. Bir müşteri hesabının olup olmadığını belirleyen bir yöntemi çağırırsanız, bir boole değeri döndürün, bir "CustomerNotFound" istisnası döndürmeyin.
  3. Bir istisnayı işleyip işlemeyeceğinizi belirlerken, istisna ile faydalı bir şey yapamadığınız sürece "try ... catch" cümlesi kullanmayın. İstisnayı idare edemiyorsanız, çağrı yığınını kabarmasına izin vermelisiniz. Aksi takdirde, istisnalar işleyici tarafından "yutulabilir" ve ayrıntılar kaybolur (istisnayı yeniden atmadıkça).

2
Durumun geri dönmesi zor bir şeydir. Başarı durumunda bir Müşteri varlığını döndüren bir GetCustomer yöntemine sahip çok fazla kod gördüm veya başarısızlık durumunda boş bıraktım. Birçok durumda, arayan kod sonucu hiçbir zaman kontrol etmez, ancak Müşteriye anında erişir. Bu çoğu zaman işe yaradı ...
TrueWill

3
Ancak GetCustomer boş döndürmek yerine bir istisna atarsa, istemci kodunun yine de istisnayı işlemesi gerekir. Null olup olmadığını kontrol ederek veya istisnaları ele alarak, sorumluluk müşteri kodunda yatar - her şeyi düzgün yapmazsa, er ya da geç bir şey patlayacaktır.
Chris

1
@TrueWill Şablonları / jenerikleri destekleyen diller bunu günümüzde Option<T>yerine bir döndürerek çözer null. Örneğin, Guava'dan (ve diğerlerinden) bir ipucu alarak Java 8'de yeni tanıtıldı.
Maarten Bodewes

@owlstead Evet. Belki monad'ı seviyorum. Diliniz destekliyorsa ve kalıp eşleştirme sunuyorsa bu iyi bir yoldur.
TrueWill

@owlstead Yine, Chris'in söylediği şey bunun için hala güçlüdür - kullanıcının .orElse (defaultObject) işlevini veya söz konusu dilin karar verdiği deyimi çağırmayı hatırlaması gerekir. Günün sonunda sorun, hata işleme yönteminden çok programcılardır.
Pharap

9

Tipik argümanlar, belirli bir kod parçasından (dile bağlı olarak) hangi istisnaların çıkacağını söylemenin bir yolu olmadığı ve çok fazla gotos gibi olduklarından, yürütmeyi zihinsel olarak izlemeyi zorlaştırdığıdır.

http://www.joelonsoftware.com/items/2003/10/13.html

Bu konuda kesinlikle bir fikir birliği yok. Linus gibi sert çekirdekli bir C programcısının bakış açısından, istisnaların kesinlikle kötü bir fikir olduğunu söyleyebilirim. Yine de tipik bir Java programcısı çok farklı bir durumdadır.


1
C kodunun istisnaları vardır, sadece farklı bir şekilde. Her çağrıyı, ifs'deki önemsiz olmayan bir işleve bağlamanız gerekir, bu da o dili kullanmayı baş ağrısına dönüştürür!
RCIX

1
Ayrıca oldukça kötü olan setjmp/ longjmpşeyler de var .
Tim Sylvester

9
Koli bandı programcılarına değer veren ve birim testlerinin gerekli olduğuna inanmayan bir adamın tavsiyesini gerçekten almak istiyor musunuz? joelonsoftware.com/items/2009/09/23.html
TrueWill

4
Bu, konuyla ilgili argümanların kişilik referanslarıyla değiştirildiği bir tartışmada klasik bir hatadır (veya hile). Bu genellikle yozlaşan tartışmanın bir işaretidir.
Petr Gladkikh

1
@PetrGladkikh Tartışma OP'nin Linus'un görüşüne atıfta bulunmasıyla başladı ... hile, otoriteye başvurmanın yanlışlığı olarak bilinir. Tartışma sadece oradan yokuş yukarı gidebilir ve Linus'un neden istisnaları sevmediği sorusuna kişiliğine atıfta bulunarak cevap vermek "hile" olmaz.
Jim Balter

7

İstisnalar fena değil. C ++ 'ın en zarif özelliği olan C ++' ın RAII modeli ile uyumludurlar. Zaten istisnai güvenli olmayan bir sürü kodunuz varsa, bu bağlamda kötüler. Linux işletim sistemi gibi gerçekten düşük seviyeli bir yazılım yazıyorsanız, o zaman kötüler. Kodunuzu bir dizi hata dönüş kontrolüyle doldurmaktan hoşlanıyorsanız, o zaman yardımcı olmazlar. Bir istisna atıldığında (C ++ yıkıcılarının sağladığı) kaynak kontrolü için bir planınız yoksa, o zaman kötüdür.


7
RAII, istisnalar olmadan bile kullanışlıdır.
Mark Ransom

4
ancak istisnalar RAII (veya başka bir otomatik kaynak yönetimi) olmadan kullanışlı değildir.
Greg Rogers

İstisnaların uygun olmadığı ve istisnaların doğal olarak kötü olmadığı durumlara işaret etmek için +1
Pharap

4

Bu nedenle istisnalar için harika bir kullanım durumu ...

Bir projede olduğunuzu ve her denetleyicinin (yaklaşık 20 farklı ana denetleyici) bir eylem yöntemiyle tek bir üst sınıf denetleyiciyi genişlettiğini varsayalım. Sonra her denetleyici, bir durumda B, C, D nesnelerini ve başka bir durumda F, G, D nesnelerini çağırarak birbirinden farklı bir dizi şey yapar. Burada, tonlarca dönüş kodunun olduğu ve HER denetleyicinin bunu farklı şekilde ele aldığı birçok durumda istisnalar kurtarmaya geliyor. Tüm bu kodu kırdım, "D" den uygun istisnayı attım, onu süper sınıf denetleyici eylem yönteminde yakaladım ve şimdi tüm denetleyicilerimiz tutarlı. Daha önce D, son kullanıcıya anlatmak istediğimiz ancak yapamadığımız MULTIPLE farklı hata durumu için boş döndürüyordu ve ben yapmadım '

evet, her seviye ve herhangi bir kaynak temizliği / sızıntısı hakkında endişelenmemiz gerekiyor, ancak genel olarak denetleyicilerimizin hiçbirinin sonradan temizleyecek kaynakları yoktu.

Tanrıya şükür istisnalarımız vardı ya da büyük bir yeniden düzenleme yapmak zorunda kalırdım ve basit bir programlama sorunu olması gereken bir şey için çok fazla zaman harcardım.


1
+1 Okuduğum istisnaları kullanmak için en iyi argümanlardan biri. Daha ayrıntılı örnekler (yani bir UML diyagramı, bazı sözde kodlar veya bazı gerçek kodlar) kullanılabilirdi, ancak alt sınıfların tutarlı bir şekilde çalışmasını sağlamanın amacı iyi bir noktadır. Ayrıca, kanıtınızın anekdot niteliğinde olması, istisnaların gerçek durumlarda yararlı olduğunu ve herhangi bir dil özelliğinin temel amacının yararlı olduğunu gösterir.
Pharap

sadece bir ek olarak, eğer ölçeklenirseniz, bunun yerine bir istisna veya gerçek yanıtı temsil eden Try [ResponseType] 'ı döndürebilirsiniz. Daha sonra, denemek dışında gerçek istisnalar olmadan yukarıda bahsettiğim aynı kalıbı takip edebilirsiniz. O zaman sahip olduğunuz her yöntem gibi, gerekli olduğunu düşündüğüm 1 + n yanıt türünü döndürür. Bununla birlikte, ölçeklendirmede, Try'a çok benzeyen ancak daha eşzamansız programlamaya yardımcı olabilecek Gelecek [yanıt] döndürüyoruz.
Dean Hiller

2

Teorik olarak gerçekten kötüler. Kusursuz matematik dünyasında istisnai durumlar elde edemezsiniz. İşlevsel dillere bakın, yan etkileri yoktur, bu nedenle istisnai durumlar için neredeyse kaynakları yoktur.

Ancak gerçeklik başka bir hikaye. Her zaman "beklenmedik" durumlara sahibiz. Bu nedenle istisnalara ihtiyacımız var.

ExceptionSituationObserver için sözdizimi şekeri olarak istisnaları düşünebileceğimizi düşünüyorum. Sadece istisnalarla ilgili bildirimler alırsınız. Daha fazlası yok.

Go ile "beklenmedik" durumlarla başa çıkacak bir şey getireceklerini düşünüyorum. İstisnalar olarak daha az yıkıcı ve uygulama mantığı olarak daha fazla ses çıkarmaya çalışacaklarını tahmin edebilirim. Ama bu sadece benim tahminim.


2
"İşlevsel dillere bakın, yan etkileri yoktur, bu yüzden istisnai durumlar için neredeyse kaynakları yoktur." Bu çok büyük bir abartıdır.
Stephen C

3
Matematikte 5/0 nedir? Arcsin (200)? Sqrt (-1)? Math'ın pek çok istisnai durumu vardır.
Robert Fraser

3
Bu, yürütme durumları değildir ... bunların hiçbir anlamı yoktur ... ve bu nedenle istisnalar olarak uygulanabilir ... ancak ön koşulların şişeleri olarak da uygulanabilir .. bu nedenle teknik uygulamaya bağlıdır.
Mike Chaliy

3
@MikeChaliy - Özür dilerim, ama bu sadece bilgelik. Bu tür bir akıl yürütmeyi hiçbir şeyde HİÇBİR istisna durum olmadığını söylemek için uygulayabilirsiniz. Gerçekte, anlamı olmayan (veya belirli bir değeri olmayan) matematiksel ifadeler istisnaidir. Bu, istisnaları fırlatıp yakalayarak ele alınmaları gerektiği anlamına gelmez ... ancak bunu yapmazsanız, ya özel değerlere (Inf ve Nan gibi) ya da birden çok değer döndüren işlemlere ihtiyacınız vardır. Kısacası bu durumlar bir tür özel tedavi gerektirir .
Stephen C

1
Bilgisayarlar durum makineleridir. Mükemmel bir matematik dünyası değil.
Arunav Sanyal

1

C ++ 'ın istisna işleme paradigması, Java'nınki için kısmi bir temel oluşturur ve buna karşılık .net, bazı iyi kavramlar sunar, ancak aynı zamanda bazı ciddi sınırlamalara sahiptir. İstisna işlemenin temel tasarım amaçlarından biri, yöntemlerin kendi son koşullarını karşılamalarını veya bir istisna atmalarını sağlamalarına izin vermek ve ayrıca bir yöntem çıkmadan önce yapılması gereken herhangi bir temizliğin gerçekleşmesini sağlamaktır. Ne yazık ki, C ++, Java ve .net'in istisna işleme paradigmalarının tümü, beklenmedik faktörlerin beklenen temizliğin gerçekleştirilmesini engellediği durumda durumu ele almak için iyi bir yol sağlamada başarısız olur. Bu da, beklenmedik bir şey olursa, birinin her şeyin çığlık atarak durma riskini alması gerektiği anlamına gelir (bir istisnayı ele almaya yönelik C ++ yaklaşımı, yığın çözme sırasında oluşur),

İstisna işleme genel olarak iyi olsa bile, diğer sorunlardan sonra temizlik yaparken ortaya çıkan sorunları ele almak için iyi bir yol sağlamayan bir istisna işleme paradigmasını kabul edilemez olarak görmek mantıksız değildir. Bu, çoklu hata senaryolarında bile mantıklı davranışlar sağlayabilecek bir istisna işleme paradigmasıyla bir çerçeve tasarlanamayacağı anlamına gelmez, ancak en iyi dillerin veya çerçevelerin hiçbiri henüz bunu yapamaz.


1

Diğer tüm cevapları okumadım, bu yüzden bu maddeden daha önce bahsedilmişti, ancak bir eleştiri, programların uzun zincirler halinde kırılmasına neden olarak kodda hata ayıklarken hataları bulmayı zorlaştırmasıdır. Örneğin, Foo (), ToString () 'i çağıran Wah ()' ı çağıran Bar () 'ı çağırırsa, yanlışlıkla yanlış verileri ToString ()' e itmek, neredeyse tamamen alakasız bir işlev olan Foo () 'da bir hata gibi görünmeye başlar.


En azından Java'da, içinde ToString () ile birlikte tüm çağrı zincirini gösterecek her istisna için yığın izine sahip olacaksınız.
ddekany

0
  • İstisnanın ele alınmaması genellikle kötüdür.
  • Kötü bir şekilde ele alınan istisna kötüdür (elbette).
  • İstisna işlemenin 'iyiliği / kötülüğü', içeriğe / kapsama ve uygunluğa bağlıdır ve bunu yapmak adına değil.

0

Tamam, sıkıcı cevap burada. Sanırım bu gerçekten dile bağlı. Bir istisnanın tahsis edilen kaynakları geride bırakabileceği durumlarda, bunlardan kaçınılmalıdır. Komut dosyası yazma dillerinde, uygulama akışının bazı kısımlarını atlarlar veya aşarlar. Bu kendi başına sevimsizdir, ancak istisnalar dışında neredeyse ölümcül hatalardan kaçmak kabul edilebilir bir fikirdir.

Hata sinyallemesi için genellikle hata sinyallerini tercih ederim. Her şey API'ye, kullanım durumuna ve önem derecesine veya günlük tutmanın yeterli olup olmadığına bağlıdır. Ayrıca davranışı yeniden tanımlamaya çalışıyorum ve throw Phonebooks()bunun yerine. "İstisnaların" genellikle çıkmazlar olduğu fikri, ancak bir "Telefon Rehberi" hata kurtarma veya alternatif yürütme yolları hakkında yararlı bilgiler içerir. (Henüz iyi bir kullanım alanı bulamadık ama denemeye devam edin.)


0

Benim için sorun çok basit. Birçok programcı, istisna işleyiciyi uygunsuz bir şekilde kullanır. Daha fazla dil kaynağı daha iyidir. İstisnaları idare edebilmek iyidir. Kötü kullanımın bir örneği, tamsayı olması gereken, doğrulanmayan bir değerdir veya bölünebilen ve sıfıra bölme için kontrol edilmeyen başka bir girdi ... istisna işleme, daha fazla işten ve zor düşünmeden kaçınmanın kolay bir yolu olabilir, programcı kirli bir kısayol yapmak ve bir istisna işleme uygulamak isteyebilir ... Algoritma tarafından işlenen sorunlardan bazıları kendi doğası gereği belirsizse, "profesyonel bir kod ASLA başarısız olmaz" ifadesi yanıltıcı olabilir. Belki de doğası gereği bilinmeyen durumlarda istisna işleyicisi devreye girer. İyi programlama uygulamaları tartışma konusudur.


Sorun, kodun başarısız olup olmayacağı değildir (veya olmamalıdır) - daha büyük bir sorun, kodun başarısız olması durumunda ayrıntıların dikkate alınma ölçüsüdür. Bir belge yüklemeye çalışırsa ve "veri okuma" yöntemlerinden biri başarısız olursa, hangisi olursa olsun, etkisi aynı olduğu için çoğu zaman gerçekten umursamaz: belge yüklenemez. Kavramsal olarak, istisna yönetimi bunun için iyi olmalıdır. Sorun şu ki, .NET ve Java'nın istisna işleme paradigmaları, bir araya getirilmesi gereken "sıkıcı" istisnaları olmaması gerekenlerden ayırt etmenin güzel bir yolunu sağlamıyor.
supercat
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.