“Programlama hatası” istisnaları - Yaklaşımım sağlam mı?


9

Şu anda istisnaları kullanımımı geliştirmeye çalışıyorum ve programlama hatalarını (örn. Birisi bağımsız değişken olarak boş geçti veya bir nesneye atıldıktan sonra bir yöntem çağırdı) istisnalar ve arayanın hatası olmayan işlem (örn. bir G / Ç istisnası).

Bu iki istisna nasıl farklı şekilde ele alınmalıdır? Hata istisnalarının açıkça belgelenmesi gerektiğini mi düşünüyorsunuz, yoksa ilgili ön koşulları belgelemek yeterli mi? Ve açık olması gerekiyorsa bir ön koşul veya hata istisnasının belgelerini dışarıda bırakabilir misiniz (örneğin, ObjectDisposedExceptionatılan bir nesnede bir yöntem çağırırken)


Genellikle başka bir istisna kategorisini ayırt ederim: iş istisnaları. Bunlar, kullanıcının ayrıntılarıyla ilgilendiği hata koşullarını ifade eder. Genellikle bu istisnaları kontrol ettiririm.
beluchin

Yanıtlar:


2

Ben doğru yolda olduğunu düşünüyorum. Potansiyel olarak atılabilir tüm istisnaları atmak, yakalamak veya belgelemek çok mantıklı değildir. Ürün zorluğunun daha yüksek derecede istisnai istihdam ve dokümantasyon gerektirdiği zamanlar vardır (örneğin, bir sistemin güvenlik açısından kritik bazı yönleri).

Özellikle savunma görevlileri (örn. Herkese açık veya korunan bir üyeye benzeyen herhangi bir şey) üzerindeki ön koşulları (ve son koşulları) tanımlamak için sözleşme kavramlarını kullanarak daha savunmacı olma stratejisi genellikle daha etkili ve daha esnek olacaktır. Bu sadece uygulama için değil, belgeler için de geçerlidir. Geliştiriciler neyin beklendiğini biliyorlarsa, kurallara uyma olasılıkları daha yüksektir ve karıştırdığınız veya yazdığınız kodu kötüye kullanma olasılığı daha düşüktür.

Belgelenmesi gereken yaygın şeylerden bazıları null parametreleridir. Çoğunlukla kullanımlarının, sonucu normalde beklenmeyen bir şeye yönlendiren, ancak bazen esneklik için çeşitli nedenlerle izin verilen ve kullanılan bir sonuç vardır. Boş veya diğer özel, rasyonel olmayan değerlere (negatif zaman veya negatif miktarlar gibi) izin veren parametrelere sahip bir üyenin tüketicisi olarak, bunların tanımlanmasını ve açıklanmasını bekliyorum.

Null olmayan parametreler için, genel veya korunan bir üyenin tüketicisi olarak null değerine izin verilmediğini bilmek istiyorum. Verilen bağlamdaki geçerli değer aralığının ne olduğunu bilmek istiyorum. Normal aralığın dışında, ancak farklı bir çağrı bağlamında geçerli olan değerleri kullanmanın sonuçlarını bilmek istiyorum (örneğin, türün değeri genellikle herhangi bir işlem için geçerlidir, ancak burada değil - boolean bir parametre gibi geçerli bir değer olarak false değerini beklemez.

Platform veya başka türlü iyi bilinen arayüzlere gelince, bunu belgelemek için aşırı uçlara gitmeniz gerektiğini düşünmüyorum. Bununla birlikte, bir geliştirici olarak, uygulamayı hangi platform rehberliğinden farklı olarak değiştirme fırsatına sahip olduğunuzdan, bu rehberliğin nasıl değerli olabileceğine dikkat edin.

IDisposable'a özgü, genellikle bu arayüzün uygulamaları, açık elden çıkarma işlemi yerine tercih edilen alternatif bir yöntem sunar. Bu durumlarda, tercih edilen yöntemi vurgulayın ve açık bertarafın tercih edilmediğine dikkat edin.


Hangi değerlere izin verildiğini belgeleme ihtiyacını anlıyorum, ancak bir işlev görürseniz performReadCommand(ICommand cmd, int replySizeBytes)- cmd için null değerinin veya answerSizeBytes için negatif bir değerin kabul edilebilir olmasını bekler misiniz? IMO dokümantasyonu sadece bu değerlere gerçekten izin verilmişse gerekli olacaktır ve muhtemelen 0'un answerSizeBytes için geçerli olup olmadığını ele almalısınız.
Medo42

Her ikisi de uygulamaya bağlı olarak "geçerli" olabilir. Siz ya da ben, hatta buradaki herkes bile boş veya negatif değerlerin bu imza için uygun olmasını beklemez, ancak olabilir. Okuyucunun engelleme, kalıcı bir işlem olduğu ve cmd'nin boş olduğu durumlarda, okuyucu tarafından kullanılan komutu değiştirmemek anlamına gelebilir ve önceki komutu kullanarak bir sonraki okumaya devam edebilirsiniz. İdeal olarak, bu durumda cmd'yi bir parametre olarak takan daha uygun bir yöntem imzası tanımlanacak ve kullanılacaktır, ancak olmayabilir.
JustinC

2

İşte kendi düşüncelerim. Bunun en iyi yol olduğuna emin olmadığımı unutmayın, bu yüzden bu soruyu ilk etapta yarattım.

Anladığım kadarıyla, hemen arayan bir kişinin programlama hatası istisnalarını gerçekten ele alması pek mantıklı değil, bunun yerine ön koşulların karşılandığından emin olmalıdır. Görev sınırlarındaki yalnızca "dış" özel durum işleyicileri onları yakalamalı, böylece bir görev başarısız olursa sistemi çalışmaya devam edebilirler.

İstemci kodunun yanlışlıkla hata istisnalarını yakalamadan "başarısızlık" istisnalarını temiz bir şekilde yakalayabilmesini sağlamak için, şimdi tüm başarısızlık istisnaları için kendi istisna sınıflarımı oluşturuyorum ve bunları atan yöntemlerde belgeliyorum. Java'da istisnaları kontrol ettirirdim.

Yakın zamana kadar, bir yöntemin atabileceği tüm istisnaları belgelemeye çalıştım, ancak bazen hatanın olmayacağını gösterene kadar çağrı zincirindeki her yöntemde belgelenmesi gereken istenmeyen bir liste oluşturur. Bunun yerine, şimdi özet / parametre açıklamalarındaki önkoşulları belgeliyorum ve karşılanmadığı takdirde ne olacağını bile söylemiyorum. Fikir şu ki, insanlar bu istisnaları açıkça yakalamaya çalışmamalıdır, bu nedenle türlerini belgelemeye gerek yoktur.

Önkoşulları belgelemek için, bariz olanı belirtmek sadece gereksiz dağınıklık yaratır - eğer bir yönteme null iletmek bariz bir anlam ifade etmiyorsa, çağıran, belgelenmemiş olsa bile null değerini geçerse bir istisna beklemek zorundadır. Aynı şey ObjectDisposedException durumu için de geçerlidir - bu arabirim o kadar yaygın olarak kullanılır ki Dispose'i çağıran biri kimsenin nesneyi kullanmaya devam etmemesini sağlama sorumluluğunun farkında olacaktır.


1

Makul bir kural:

  1. Düzeltebileceğiniz herhangi bir istisnayı yakalayın.
  2. Düzeltemeyeceğiniz, ancak yararlı bir şeyler söyleyebileceğiniz istisnaları yakalayın, yorum yapın ve yeniden yazın.
  3. İşleyemediğiniz veya teşhis edemediğiniz herhangi bir istisnayı varsayılan işlemden daha iyi yakalamayın.

Uygulamanızın düşmesini önlemek için aşağıda ele alınamayan herhangi bir şeyi yakalamak için üst düzey ölümcül olmayan bir istisna işleyicisine sahip olmak isteyebilirsiniz, ancak bu, özellikle uygulamanıza bağlı olacaktır. Örneğin, iOS uygulamaları olabildiğince tuzağa düşmeyi tercih eder; bir komut satırı uygulaması, neredeyse hiçbir istisnayı yakalamazsa mükemmel bir şekilde uygun olabilir.


0

Java bile tüm istisnaları "belgelemez". Her thrown istisnanın bir throwscümlede belirtilmesi gerekliliğine rağmen , herhangi bir kod satırı RuntimeException, yöntem imzasında beyan edilmesine gerek kalmadan bir a atabilir .


Bu, popüler tavsiyeye aykırıdır - özellikle, Etkili Java, 2. baskı, Madde 62 "Her bir yöntem tarafından atılan tüm istisnaları belgeleyin". Aslında, Bloch, kontrol edilmeyen istisnaların genellikle programlama hataları için olduğunu, ancak bir yöntemin ön koşullarını belgelemenin "en iyi yolu" olduğu için bunların da dikkatle belgelenmesi gerektiğini kabul eder. Yine de aynı fikirde olup olmadığımdan emin değilim. Eğer uygulamaları belgelersem, onları arayüz sözleşmesinin bir parçası haline getiririm ve benim uygulamam değiştiğinde aynı kalmaları için kod eklemek zorunda kalabilirim.
Medo42

1
Her uzman için bir karşı uzman var. Java'da oldukça ünlü Thinking'in yazarı Bruce Eckel, bir zamanlar kontrol edilen istisnalar kampındaydı ve taraf değiştirdi. Bir var Eckels Anders Hejlsberg arasındaki güzel tartışma istisnalar kontrol ettikten etmez C # yaratıcısı.
Ross Patterson

0

Bunu yapmanın standart yolu java yaklaşımıdır. Programlama hataları işaretlenmemiş istisnalar olmalı ve hızlı bir hata oluşmasını sağlamak için yakalanmamalıdır. Sözleşme hataları istisnalar açısından kontrol edilir ve müşteri tarafından uygun şekilde ele alınmalıdır.


2
Eğer (örneğin) bir olarak görüyor musunuz hesaplanmış bir şekilde (ya da bir hata değerini) NULL programlama hatası veya sözleşme hatası? Senin ayrımınla gidiyorum, ama sınır o kadar net değil :)
Andrew

Null, iletilen bir argümandan (null argüman veya geçersiz bir şey gibi) hesaplanırsa, bu bir sözleşme hatasıdır. Boş kod bir parça kötü kod nedeniyle hesaplanırsa, bu bir programlama hatasıdır. Null değerinin hesaplanması gerekiyorsa, bu bir hata değildir. Bu örnekte hiçbir belirsizlik görmüyorum.
J.Ashworth
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.