it-swarm.asia

Bir yöntem parametrelerini doğrulamalı mı?

Diyelim ki bir kare kök yöntemi sqrt tasarlıyorsunuz. Geçilen parametrenin negatif bir sayı olmadığını doğrulamayı mı, yoksa geçilen parametrenin geçerli olduğundan emin olmak için onu çağırana bırakmayı mı tercih edersiniz? Yöntem/API 3. taraf tüketimi içinse veya yalnızca üzerinde çalıştığınız uygulama için kullanılacaksa cevabınız nasıl değişir?

Bir yöntemin parametresini doğrulaması gerektiği görüşündeyim, ancak Sözleşmeye Göre Tasarım bölümünde (bölüm 4) Pragmatik Programcı iyi verileri iletmenin (pg 111 ve 115) arayanın sorumluluğunda olduğunu ve yöntemde iddiaların kullanılmasını önerdiğini söylüyor aynısını doğrulamak için. Başkalarının bu konuda ne hissettiğini bilmek istiyorum.

44
Amit Wadhwa

Genel olarak, API'larımı aşağıdaki gibi tasarlıyorum:
1. Yöntemleri iyi belgelendirin ve arayanları iyi/geçerli veri aktarmaya teşvik edin.
2. Yine de parametreleri doğrulayın! - ön koşullar karşılanmadığında istisnalar atma.

Çoğu kamuya açık API'larda parametre doğrulamanın gerekli olduğunu söyleyebilirim. Herkese açık olmayan yöntemlerde parametre doğrulaması o kadar önemli değildir - onaylamanın genel 'giriş noktasında' yalnızca bir kez gerçekleşmesi istenir - ancak potansiyel performans isabeti ile yaşayabiliyorsanız, parametreleri her yerde doğrulamak istiyorum kod bakımını ve yeniden düzenlemeyi biraz daha kolaylaştırır.

34
Matthew King

Parametreleri her zaman doğrularsanız, gerekli olmayabilecek ekstra işler yapıyorsunuz demektir.

Aramadan önce girişin zaten doğrulanmış olduğu durumu düşünün ve şimdi aramadaki verileri yeniden doğrulıyorsunuz. Tamam bir ekstra doğrulama kontrolü tamam, ancak şimdi bu mantığı uygulamanızdaki tüm işlevlere genişletir. Her işlev çağrısı, daha önce doğrulanmış olmasına rağmen (şimdi birden çok kez) verileri doğrular.

Veriler BIR noktasında doğrulanmalıdır. Bu, verilerin programa girdiği yerdir (veya alt sistem (bu, alt sistem tanımı esnek olabileceğinden bir miktar avantaj sağlar)). Programlama hatası yoksa, kodunuzun şimdi çalışması gerekir (Hatalı kodu kontrol etmek için not iddiaları parametreleri doğrulamaktan farklıdır).

Parametreleri gerçekten doğrulamak istiyorsanız, işlevin iki sürümüne sahip olun. Biri valide eder ve diğeri valide etmez. Std :: vector'a bakın (() operatörü [] doğrulamaz, () doğrulamaz).

Bu yüzden bir sqrt () işlevi tasarlamak zorunda kalsaydım değil girişlerini doğrulardı çünkü durumların çoğunda yine de veri iyi olurdu ve kullanıcının potansiyel olarak yanlış olduğu durumların küçük azınlığı hızlı bir kontrol yapın (kullanıcı girişi gibi yanlış olabilir ve kullanımdan önce doğrulanması gerekir). Yanlış olan tek zaman programcı hatasıdır (ve birim testleriniz bunları yakalamalıdır).

26
Martin York

Karmaşık yazılım ne kadar fazlalık/sağlamlık uygulamalıdır? ilgili bir soru sorar.

Cevabım, dış dünyayla etkileşime giren işlevlerin (genel API'lar, UI yöntemleri, dosya okuyucular, vb.) Girdiyi doğrulaması ve kullanıcıyı mümkün olduğunca nazik ve net bir şekilde bilgilendirmesi gerektiğidir. En azından hata mesajı/dönüş kodu, kötü girişin nerede meydana geldiğini ve ne tür bir kısıtlamayı ihlal ettiğini belirtmelidir. Ne kadar spesifik olursa o kadar iyidir.

Öte yandan, yalnızca dahili olarak oluşturulan verilerle veya dışa dönük işlevlerden biri tarafından zaten işlenmiş verilerle ilgilenen özel işlevler, başarılı bir şekilde çalışması için gereken ön koşullardan herhangi birine sahip olmalıdır. Bir programcı bunları ihlal eden kod yazarsa, programın başarısız olması ve başarısız olması gerekir. Bu tür hatalar asla ilk test aşamalarını geçmemelidir.

Buradaki motivasyon, kullanıcılar için olabildiğince iyi olmakla birlikte, aynı zamanda kötü girdileri nasıl ele alacağınıza ilişkin kararları mümkün olduğunca yüksek bir seviyeye sınırlamaktır. Düşük düzeyli bir işlev her yazdığınızda, program düzeyinde hata işleme stratejinizin bir sonraki parçasını bulmak istemezsiniz.

Yani: kullanıcı girişini, programcı girişini onayla.

17
AShelly

Bir yazı sisteminiz varsa bunu kullanın.

İddialar kötülüğü erken yakalamaya yardımcı olacaktır.

null olmayan kısıtlamalar makul bir şeydir.

sqrt (-1) bazı programlama dillerinde hata değildir. Karmaşık sayı desteğine sahip Smalltalk'in i i değerini döndürür.

10
Tim Williscroft

Bence uygulama teorisinden ziyade yöntemin uygulanmasına bağlı.

Demek istediğim: Hızlı bir matematik kütüphanesi inşa ediyorsanız, herkes tarafından kullanılabilse bile, en azından 'serbest bırakma' modunda inşa edildiğinde değil, çalışma zamanı kontrolleri yapmak istemezsiniz, çünkü hız değerlendiricidir ölçütü. Denetimleri 'hata ayıklama' modunda uygulayabilirsiniz, çünkü davranışlar modlar arasında tutarlı olmasını istediğinizden, iddiaları kullanarak. Tabii ki, bu tür bir davranışı çok iyi belgelemek istiyorsunuz, bu yüzden kütüphanenizin kullanıcıları (üç ay içinde siz olsanız bile!) Hangi kontrollerin yapıldığını biliyor onlar.

Şimdi, bir ağ iletişim kütüphanesi inşa ediyorsanız, olabildiğince fazla güvenlik eklemek istersiniz, çünkü 1) çoğunlukla kullanıcı girdisi ile beslenecek, dolayısıyla tehlike 2) ham performans çoğunlukla ağ G/Ç ile bağlanacaktır, CPU işlemiyle değil, bu nedenle bazı doğrulamaların eklenmesi bile fark edilmeyecektir.

8
jv42

Her işlev girdisini doğrulamalıdır, herhangi bir API veya ortak arabirimin parçası olmayan dahili işlevler bile.

Programcılar insandır ve insanlar büyük kod tabanları geliştikçe ilgili kısıtlamaları senkronize tutmakta kötü bir şekilde beceriksizdir - sonuç olarak, "çağrı fonksiyonu" öncesinde gerçekleşen "girişi kontrol et" kısmı kaybolur veya başka bir yere taşınır veya tamamlanmaz ve işlevi yanlış girişle çağrılır. Bu olduğunda, en iyi iki hedefiniz:

  • Sorunu olabildiğince çabuk tespit edin (derleme zamanı en iyi seçenektir)
  • Sorun çözülene kadar hiçbir şeyi kırma

Birçok şey için, hangi özelliklerin doğrulandığı hakkında derleme zamanı bilgisi taşımak için dil özelliklerini veya tür sistemini kullanabilirsiniz. Bu hem son derece hızlıdır (çalışma zamanı cezası yoktur) ve derleme zamanında hataları algılar. Örneğin, doğrulamalarımın çoğu bu kategoridedir.

Diliniz yaptığınız şey için derleme zamanı doğrulamasını desteklemiyorsa (modern dillerde oldukça nadirdir), bir çalışma zamanı iddiası ekleyin.

Yalnızca kodunuzun başarısız olması, kolayca tespit edilebilen ve zararsız bir hatanın ötesinde olumsuz sonuçlara yol açamazsa ve bu kodun çok sık çağrılmasını beklerseniz ve doğrulama, fonksiyon kodu yine de , doğrulamaları dışarıda bırakabilirsiniz. sqrt muhtemelen burada olurdu.

2
Victor Nicollet

C/C++ ve işlevsel önişlemci sağlayan diğer diller için, giriş parametrelerini yalnızca Hata Ayıklama/Test için derlendiğinde doğrulayabilir ve onaylanmamış Sürüm derlemesi üretebilirsiniz.

Visual C++ MFC kitaplığı iyi örneklerden biridir.

Aşağıda MFC genel örneklerinden örnek kod verilmiştir:

void CServerNode::CalcBounding(CDC* pDC, CPoint& ptStart, CSize& sizeMax)
{
    ASSERT(sizeMax.cx >= 0 && sizeMax.cy >= 0);
    ASSERT(ptStart.x >= 0 && ptStart.y >= 0);

    CSize sizeNode;
    CalcNodeSize(pDC, sizeNode);

    ptStart.y += sizeNode.cy + CY_SEPARATOR;
    if (ptStart.y > sizeMax.cy)
        sizeMax.cy = ptStart.y;

    if (ptStart.x + sizeNode.cx > sizeMax.cx)
        sizeMax.cx = ptStart.x + sizeNode.cx;
    ptStart.x += CX_INDENT;
    // add in the kids
    if (!m_bHideChildren)
    {
        POSITION pos = m_listChild.GetHeadPosition();
        while (pos != NULL)
        {
            CServerNode* pNode = (CServerNode*)m_listChild.GetNext(pos);
            pNode->CalcBounding(pDC, ptStart, sizeMax);
        }
    }
    ptStart.x -= CX_INDENT;
}
2
9dan

Veritabanından gelen veriler, HTTP POST veya bir ağ soketindeki veriler) olsun, gelen verilerin kaynağına her zaman doğrulama koyarım.

Bunun nedenleri:

  • kodun azaltılması
  • gereksiz operasyonların ortadan kaldırılması
  • daha basit kod (genellikle)

Bununla birlikte, çoğu programlama kuralında veya en iyi uygulamada her zaman istisnalar olacaktır. Bu istisnaları tanımanın anahtarı, bir dizi kurala körü körüne bağlı kalmaktan ziyade, her bir durumu dikkatle düşünmek ve değerlendirmektir.

1
dietbuddha

Her işlevin giriş parametrelerinin geçerliliğini doğrulaması gerektiğini düşünüyorum ve derleme zamanında doğrulanabilirse daha iyidir (statik olarak yazılan bir dil kullanıyorsanız, tip sisteminin yardımıyla).

Giriş parametrelerinin geçerli olduğundan emin olmak için iddiaları kullanma fikri benim için biraz garip görünüyor - esasen, aynı kontrolleri iki kez yazmanız gerektiği anlamına geliyor - bir kez arayan işlevinde ve yöntemde ikinci kez iddialar şeklinde. Bu aynı zamanda, giriş parametreleriyle ilgili gereksinimler değiştiğinde, sadece arayan değil, arama işlevlerinin her yerindeki kontrolleri değiştirmeniz gerektiği anlamına gelir.

Öyleyse neden sadece yöntemin kendisindeki parametreleri doğrulamak ve bir tutarsızlık bulunduğunda bir istisna oluşturmak (veya uygun olanı yapmak) değil?

1
user21125

Her zaman basit şemayı kullanıyorum: yöntemleri çağırmak için UI ve basit kod (UI parametrelerini doğrula) -> Yöntemler (UI parametrelerini değil doğrular) -> Ek İşlevler (hiçbir şeyi doğrulamazlar)

0
cnd