Geri dönmek kötü bir tasarım mı? [kapalı]


127

Yöntemlerden dönen bir boş değeri kontrol etmenin kötü tasarım olduğunu söyleyen bazı sesler duydum. Bunun için bazı nedenler duymak istiyorum.

pseudocode:

variable x = object.method()
if (x is null) do something

13
Ayrıntılı: Kötü olduğunu söyleyen bu insanlar nerede? Bağlantılar?
jcollum

2
Eğer yöntem üzerinde kontrol sahibi olduğunuz bir şeyse, hiçbir zaman null döndürmediğinden emin olmak için birim testlerine sahip olabilirsiniz, aksi takdirde, bu çağrıdan sonra boş olup olmadığını kontrol etmenin neden kötü bir uygulama olacağını anlamıyorum; boş döndürmek bu yöntemde kötü bir uygulama olabilir, ancak kodunuzu korumalısınız
BlackTigerX

9
Sırf iade edilecek veri olmadığı için istisnaların ortaya çıkarılması son derece can sıkıcıdır. Normal program akışı istisna oluşturmamalıdır.
Thorarin

4
@David: Ben gerçekten öyle dedim. Bir yöntemin veri döndürmesi gerekiyorsa, ancak hiçbiri yoksa, bu da bir şeylerin ters gittiği anlamına gelir. Bu normal program akışı değil :)
Thorarin

2
@Thorarin: "normal" program akışı oldukça uzatılabilir bir kavram: bir argüman için gerçekten sağlam bir temel değil.
Tomislav Nakic-Alfirevic

Yanıtlar:


206

Boş değer döndürmemenin ardındaki mantık, onu kontrol etmeniz gerekmemesi ve dolayısıyla kodunuzun dönüş değerine göre farklı bir yol izlemesine gerek olmamasıdır . Bununla ilgili daha fazla bilgi sağlayan Boş Nesne Kalıbı'na göz atmak isteyebilirsiniz .

Örneğin, Java'da bir Koleksiyon döndüren bir yöntem tanımlayacak olsaydım, genellikle Collections.emptyList()istemci kodumun daha temiz olduğu anlamına geldiğinden boş bir koleksiyon (yani ) döndürmeyi tercih ederdim ; Örneğin

Collection<? extends Item> c = getItems(); // Will never return null.

for (Item item : c) { // Will not enter the loop if c is empty.
  // Process item.
}

... şundan daha temizdir:

Collection<? extends Item> c = getItems(); // Could potentially return null.

// Two possible code paths now so harder to test.
if (c != null) {
  for (Item item : c) {
    // Process item.
  }
}

6
Evet, boşa dönmekten ve müşterinin vakayla ilgilenmeyi hatırlamasını ummaktan çok daha iyi.
djna

10
Boş kapların (veya dizelerin) yerine kullanıldığında boş döndürmenin çılgınca olduğuna memnuniyetle katılıyorum. Yine de yaygın durum bu değil.
MSalters

2
Benim için de Boş Nesne Kalıbı için +1. Ayrıca aslında null döndürmek istediğimde, yöntemi açıkça belirtmek için getCustomerOrNull () gibi adlandırıyorum. Okuyucu uygulamaya bakmak istemediğinde bir yöntemin iyi adlandırıldığını düşünüyorum.
Mike Valenty

4
'// Şimdi iki olası kod yolu' açıklaması doğru değil; her iki şekilde de iki kod yolunuz var. Ancak, ilk örneğinizdeki boş Koleksiyon nesnesiyle, 'boş' kod yolu daha kısadır. Yine de iki yolunuz var ve yine de iki yolu test etmeniz gerekiyor.
Frerich Raabe

1
@MSalters - Muhtemelen OO dillerindeki her değişken, nullnesnelere sıfır veya bir işaretçi içeren bir "kapsayıcıdır". (Bu gibi Maybedurumlarda Haskell'in açıkça modellediği kesinlikle bu ve bunu yapmak için daha iyi.)
Andrzej Doyle

71

Nedeni burada.

In Robert Martin Temiz Kanunu o null adlı dönen kötü yerine dönebilir tasarımı, diyelim ki, boş bir dizi yazıyor. Beklenen sonuç bir dizi olduğuna göre, neden olmasın? Herhangi bir ekstra koşul olmadan sonucu yinelemenizi sağlar. Eğer bir tamsayı ise, belki 0, bir karma ise boş bir karma ise yeterli olacaktır. vb.

Buradaki önerme, arama kodunu sorunları hemen ele almaya zorlamamaktır. Arama kodu onlarla ilgilenmek istemeyebilir. Bu yüzden çoğu durumda istisnalar sıfırdan daha iyidir.


2
Bu, bu yanıtta bahsedilen Boş Nesne Modeli: stackoverflow.com/questions/1274792/…
Scott Dorman

Buradaki fikir, hata durumunda, normal olarak döndürmek istediğiniz nesne türünün boş / boş bir sürümünü döndürmenizdir. Örneğin, boş bir dizi veya dizge bu durumlarda işe yarar. Normalde bir gösterici döndürdüğünüzde "NULL" döndürmek uygundur (çünkü NULL aslında boş bir göstericidir). Normalde bir hash döndüren bir işlevden hata durumunda NULL döndürmek kafa karıştırıcı olabilir. Bazı diller bunu diğerlerinden daha iyi ele alır, ancak genel olarak tutarlılık en iyi uygulamadır.
bta

Hata bir şekilde akışı kontrol etmedikçe (bu iyi bir uygulama değildir) veya API veya arayüzde özetlenmedikçe, mutlaka hata durumunda geri dönmezsiniz. Onu yakalamaya karar verdiğiniz herhangi bir seviyeye yaymak için hatalar vardır, dolayısıyla arama bağlamında bununla uğraşmak zorunda kalmazsınız. Varsayılan olarak boş nesne deseni dostudurlar.
Max Chernyak

Ne yazık ki, kod çağırmak her zaman boş bir koleksiyon durumunu dikkate almaz (tıpkı boş durumu dikkate almaması gibi). Bu bir sorun olabilir veya olmayabilir.
Sridhar Sarnobat

38

Boş değer döndürmenin iyi kullanımları:

  • Null geçerli bir işlevsel sonuçsa, örneğin: FindFirstObjectThatNeedsProcessing () bulunmazsa null döndürebilir ve arayanın buna göre kontrol etmesi gerekir.

Kötü kullanımlar: Aşağıdakiler gibi istisnai durumları değiştirmeye veya gizlemeye çalışma:

  • catch (...) ve boş döndür
  • API bağımlılığı başlatılamadı
  • Disk alanı dolu
  • Geçersiz giriş parametreleri (programlama hatası, girişler arayan tarafından temizlenmelidir)
  • vb

Bu gibi durumlarda bir istisna yapmak daha uygundur çünkü:

  • Boş bir dönüş değeri anlamlı hata bilgisi sağlamaz
  • Anında arayan kişi büyük olasılıkla hata durumunu işleyemez
  • Arayanın boş sonuçları kontrol ettiğinin garantisi yoktur

Ancak, istisnalar aşağıdaki gibi normal program çalıştırma koşullarını işlemek için kullanılmamalıdır:

  • Geçersiz kullanıcı adı / parola (veya kullanıcı tarafından sağlanan herhangi bir giriş)
  • Kırılma döngüleri veya yerel olmayan gotos olarak

7
Yine de "geçersiz kullanıcı adı" bir İstisna için iyi bir neden gibi görünüyor.
Thilo

11
Geçersiz oturum açma / parola giren kullanıcılar, normal program işleminin bir parçası olan istisnai koşullar olarak değerlendirilmemelidir. Ancak, yanıt vermeyen kimlik doğrulama sistemi (örneğin, aktif dizin) istisnai bir durumdur.
ZeroConcept


2
boolean login(String,String)AuthenticationContext createAuthContext(String,String) throws AuthenticationException
Duruma göre

1
Örneğinizde, işlenmesi gereken ilk nesne yoksa, bu durumu ele almanın iki makul yolu vardır. İlki Boş Nesne kalıbıdır. Sınıfın var olmayan bir sürümünü temsil eden son bir alt sınıf oluşturun. Makul varsayılanlara sahiptir ve saçma eylemler talep edildiğinde istisnalar atar. Diğer teknik ise Seçenek. Java8 ve Scala'da mevcut olan budur. Bunlardan herhangi biri geliştiricilerin niyetini gösterir. null, çok fazla olası anlamı olduğu için amacı gösteremez. ** Niyeti Gösterme **, kodun en önemli yönüdür.
scott m gardner

29

Evet, NULL döndürmek , nesne yönelimli dünyada korkunç bir tasarımdır . Özetle, NULL kullanımı şunlara yol açar:

  • geçici hata işleme (istisnalar yerine)
  • belirsiz anlamsal
  • hızlı başarısız olmak yerine yavaş
  • nesne düşünme yerine bilgisayarla düşünme
  • değişken ve eksik nesneler

Ayrıntılı bir açıklama için bu blog gönderisine bakın: http://www.yegor256.com/2014/05/13/why-null-is-bad.html . Daha fazlası kitabımda Elegant Objects , Kısım 4.1.


2
Kesinlikle katılıyorum 'Badana' geciktirme taktiği gibi görünen boş nesne modelini bile sevmiyorum. Yönteminizin ya her zaman başarılı olacağı varsayılır ya da olmayabilir. Her zaman başarılı olursa, at. Başarılı olamazsa, yöntemi tüketicinin bileceği şekilde tasarlayın, örneğin bool TryGetBlah(out blah)veya FirstOrNull()veya MatchOrFallback(T fallbackValue).
Luke Puplett

Ben de boş dönmeyi sevmiyorum. Temel nedeni belirtiden ayırarak hata ayıklamayı zorlaştırırsınız. Ya bir istisna atın (hızlı başarısızlık) ya da önce bir boole döndüren (örn. isEmpty()) Bir kontrol yöntemi çağırın ve yalnızca doğru ise yöntemi çağırın. İnsanlar, ikincisine karşı tartışıyorlar, performansın daha düşük olduğunu söylüyor - ancak Unix Philosophy'nin dediği gibi, "makine zamanına göre insan zamanına değer verin" (yani, önemsiz ölçüde daha yavaş performans, sahte hatalar veren kod hata ayıklama geliştiricilere göre daha az zaman harcar).
Sridhar Sarnobat

22

Bunun kötü bir tasarım olduğunu kim söylüyor?

Boş değerleri kontrol etmek yaygın bir uygulamadır, hatta teşvik edilir, aksi takdirde her yerde NullReferenceExceptions riskiyle karşılaşırsınız. İhtiyacınız olmadığında istisnalar atmaktansa hatayı incelikle ele almak daha iyidir.


11
+1. Anında hafifletilebilecek sorunlar için istisnalar atan kod beni üzüyor.
jkeys

6
Kodlayıcılar sıfırları kontrol etmeyi unutup gizemli boş işaretçi istisnaları aldığında ne kadar üzülürsünüz? Derleyicinin kullanıcıya hata durumlarıyla ilgilenmediğini hatırlattığı istisnalar, kodlama hatalarını önler.
djna

3
@djna: Sanırım bu da üzücü ama boşları kontrol etmeyi "unutan" aynı tür kodlayıcıların, kontrol edilen istisnalarla uğraşırken sıklıkla onları yutanlar olduğunu gördüm.
Randy Monica'yı

5
Boş bir yakalama bloğunun varlığını fark etmek, sıfır kontrolünün olmamasından daha kolaydır.
Preston

20
@Preston: Kesinlikle katılmıyorum. Boş kontrolün olmaması, çöktüğünde hemen fark edeceksiniz. Yutulan istisnalar yıllarca gizemli ve ince hatalar doğurabilir ...
Beska

18

Şimdiye kadar söylediklerinize dayanarak, yeterli bilgi olmadığını düşünüyorum.

CreateWidget () yönteminden boş değer döndürmek kötü görünüyor.

FindFooInBar () yönteminden boş değer döndürmek iyi görünüyor.


4
Kuralıma benzer: Tek öğeli sorgular - Create... yeni bir örnek döndürür veya atar ; Get...beklenen mevcut bir örneği döndürür veya atar ; GetOrCreate...mevcut bir örneği veya yoksa yeni bir örneği döndürür veya atar ; Find...varsa, mevcut bir örneği döndürür veyanull . Koleksiyon sorguları için - Get... her zaman eşleşen öğe bulunamazsa boş olan bir koleksiyon döndürür.
Johann Gerell

Yegor256 & hakuinin'in cevabında verilen nedenlerden ötürü NULL kötüdür, geçerli ama boş bir nesneyi döndürmek, muhakemeyi basitleştirir
Rob11311


10

Kullandığınız dile bağlıdır. Bir değerin eksikliğini belirtmenin deyimsel yolunun null döndürmek olduğu C # gibi bir dildeyseniz, değeriniz yoksa boş döndürmek iyi bir tasarımdır. Alternatif olarak, bu durum için deyimsel olarak Belki monadını kullanan Haskell gibi dillerde, boş döndürmek kötü bir tasarım olurdu (hatta mümkün olsaydı).


2
Belki monad'dan bahsetmek için +1. nullC # ve Java gibi dillerdeki tanımlarının genellikle aşırı yüklendiğini ve etki alanında bir miktar anlam verildiğini görüyorum . Eğer yukarı bakacak olursak nulldil özellikleri anahtar kelime, sadece "geçersiz işaretçi" anlamına gelir. Bu muhtemelen herhangi bir sorun alanında hiçbir şey ifade etmiyor.
MattDavey

Sorun şu ki, bunun "eksik değer" mi nullyoksa "başlatılmamış" mı olduğunu bilmiyorsunuznull
CervEd

5

Tüm cevapları okursanız, bu sorunun cevabı yöntemin türüne bağlıdır.

İlk olarak, istisnai bir şey olduğunda (IOproblem vb.), Mantıksal olarak istisnalar atılır. Tam olarak bir şey olağanüstü olduğunda, muhtemelen farklı bir konu için bir şeydir ..

Bir yöntemin herhangi bir sonuca sahip olmaması beklendiğinde, iki kategori vardır:

  • Nötr bir değer döndürmek mümkünse , bunu yapın .
    Boş numaralandırmalar, dizeler vb. İyi örneklerdir
  • Böyle nötr bir değer yoksa, null döndürülmelidir .
    Belirtildiği gibi, yöntemin muhtemelen bir sonucu olmadığı varsayılır, bu nedenle istisnai değildir, dolayısıyla bir istisna atmamalıdır. Nötr bir değer mümkün değildir (örneğin: 0, programa bağlı olarak özellikle nötr bir sonuç değildir)

Bir işlevin boş dönebileceğini veya dönmeyeceğini belirtmenin resmi bir yolunu bulana kadar, bunu belirtmek için bir adlandırma kuralına sahip olmaya çalışıyorum. Başarısız olması beklenen yöntemler
için Try Something () kuralınız olduğu gibi, genellikle yöntemlerimi Güvenli Bir Şey () olarak adlandırırım. , yöntem null yerine nötr bir sonuç döndürdüğünde olarak adlandırırım.

Henüz isim konusunda tam olarak uygun değilim, ancak daha iyi bir şey bulamadım. Bu yüzden şimdilik bununla koşuyorum.


4

Bu alanda bana iyi hizmet eden bir kongrem var

Tek öğe sorguları için:

  • Create...yeni bir örnek döndürür veya fırlatır
  • Get...beklenen mevcut bir örneği döndürür veya atar
  • GetOrCreate...mevcut bir örneği veya yoksa yeni bir örneği döndürür veya atar
  • Find...varsa, mevcut bir örneği döndürür veyanull

Koleksiyon sorguları için:

  • Get... her zaman eşleşen [1] öğe bulunmazsa boş olan bir koleksiyon döndürür

[1] işlev adında veya parametrelerde verilen açık veya örtük bazı kriterler verildi.


GetOne ve FindOne bulunmazsa neden farklı döndürür?
Vladimir Vukanac

Farkı anlattım. Kullandığım Getne zaman bekliyoruz orada olmak orada değil eğer öyleyse, o zaman bunun bir hata olduğuna ve ben atmak olduğunu, - ben dönüş değeri denetlemek için gerek kalmaz. FindOrada olup olmadığını gerçekten bilmiyorsam kullanırım - o zaman dönüş değerini kontrol etmem gerekir.
Johann Gerell

3

İstisnalar istisna içindir durumlar içindir.

İşlevinizin belirli bir nesneyle ilişkili bir özniteliği bulması amaçlanıyorsa ve bu nesnenin böyle bir özniteliği yoksa, boş döndürmek uygun olabilir. Nesne mevcut değilse, bir istisna atmak daha uygun olabilir. İşlevin bir öznitelik listesi döndürmesi amaçlanıyorsa ve döndürülecek hiçbir şey yoksa, boş bir liste döndürmek mantıklıdır - tüm sıfır özniteliklerini döndürüyorsunuz.


1
Değeri olmayan bir öznitelik kullanmaya çalışırsanız , bu bir istisnayı hak eder. (Spesifikasyonunuzun özniteliğin isteğe bağlı olduğunu söylediğini varsayıyorum.) Değerinin ayarlanıp ayarlanmadığını kontrol etmek için ayrı bir yönteminiz olsun.
Preston

3

Bunu yapmak bir şekilde anlamlıysa, boş döndürmek sorun değil:

public String getEmployeeName(int id){ ..}

Böyle bir durumda, kimlik mevcut bir varlığa karşılık gelmiyorsa boş döndürmek anlamlıdır, çünkü hiçbir eşleşme bulunmayan durumu meşru bir hatadan ayırt etmenize olanak tanır.

İnsanlar bunun kötü olduğunu düşünebilirler çünkü bir hata durumunu gösteren "özel" bir dönüş değeri olarak kötüye kullanılabilir, bu çok iyi olmayan bir işlevden hata kodları döndürmek gibi ancak kafa karıştırıcıdır çünkü kullanıcının dönüşünü kontrol etmesi gerekir. uygun istisnaları yakalamak yerine null, ör.

public Integer getId(...){
   try{ ... ; return id; }
   catch(Exception e){ return null;}
}

3
Evet. Bir hata durumunuz varsa, bir istisna atın.
David Thornley

3
Bu, istisnanın garanti edilebileceği bir durumdur. Var olmayan bir çalışanın adını talep ediyorsanız, açıkça bir şeyler ters gidiyordur.
Thorarin

Sanırım bu biraz gerçek, Thorarin - benim örneğimle tartışabilirsiniz, ama eminim eşleşen bir değer döndüren bir işlevin bir örneğini veya eşleşme yoksa null olduğunu hayal edebilirsiniz. Bir hashtable'daki bir anahtardan bir değer almaya ne dersiniz? (ilk etapta bu örneği düşünmeliydim).
Steve B.

1
Var olmayan bir anahtar için null döndüren bir karma tablo kötüdür. Bunu otomatik olarak yapmak, tutarsız kod olmadan boş değeri bir değer olarak saklayamayacağınız anlamına gelir.
RHSeeger

3

Bu, pek çok tasarım kararında olduğu gibi, mutlaka kötü bir tasarım değildir.

Yöntemin sonucu, normal kullanımda iyi bir sonucu olmayacak bir şeyse, null döndürmek iyidir:

object x = GetObjectFromCache();   // return null if it's not in the cache

Gerçekten her zaman boş olmayan bir sonuç olması gerekiyorsa, bir istisna atmak daha iyi olabilir:

try {
   Controller c = GetController();    // the controller object is central to 
                                      //   the application. If we don't get one, 
                                      //   we're fubar

   // it's likely that it's OK to not have the try/catch since you won't 
   // be able to really handle the problem here
}
catch /* ... */ {
}

2
Orada bir tanılama hatasını kaydedebilseniz de, belki istisnayı yeniden atabilirsiniz. Bazen İlk Arıza Verilerini Yakalama çok yardımcı olabilir.
djna

Veya bir RuntimeException özel durumundaki istisnayı ileti dizesindeki tanılama bilgileriyle sarın. Bilgileri bir arada tutun.
Thorbjørn Ravn Andersen

Şimdi (2018'de) Artık kabul edemiyorum ve bu gibi durumlarda geri dönmeyi tercih etmeliyizOptional<>
Piotr Müller

2

Bazı senaryolar için, bir arızayı meydana gelir gelmez fark etmek istersiniz.

Arıza durumunda NULL'a karşı kontrol etmek ve iddia etmemek (programcı hataları için) veya atmamak (kullanıcı veya arayan hataları için), orijinal garip durum bulunamadığından sonraki çökmelerin izini sürmenin daha zor olduğu anlamına gelebilir.

Dahası, hataları göz ardı etmek, güvenlik açıklarına yol açabilir. Belki de boşluk, bir tamponun üzerine yazılması veya benzeri olgudan kaynaklanmıştır. Şimdi, vardır değil sömürücü kodunuzda yürütmek için bir şansı var demektir çarpıyor.


2

Boş değer döndürmek için hangi alternatifleri görüyorsunuz?

İki durum görüyorum:

  • findAnItem (id). Öğe bulunamazsa bu ne yapmalı?

Bu durumda şunları yapabiliriz: Null değerini döndürür veya bir (işaretli) istisna atar (veya belki bir öğe oluşturup onu iade eder)

  • listItemsMatching (ölçütler) hiçbir şey bulunmazsa bu ne döndürmelidir?

Bu durumda Null döndürebilir, boş bir liste döndürebilir veya bir İstisna atabiliriz.

Geri dönüş boş değerinin alternatiflerden daha az iyi olabileceğine inanıyorum, çünkü istemcinin boş değeri kontrol etmeyi, programcıların unutmasını ve kodlamayı hatırlamasını gerektiriyor

x = find();
x.getField();  // bang null pointer exception

Java'da, kontrol edilen bir istisna olan RecordNotFoundException, derleyicinin istemciye vakayla ilgilenmesini hatırlatmasını sağlar.

Boş listeleri döndüren aramaların oldukça kullanışlı olabileceğini görüyorum - sadece ekranı listenin tüm içeriği ile doldurun, oh boş, kod "sadece çalışıyor".


3
Programın normal akışı sırasında gerçekleşmesi beklenen bir koşulu belirtmek için istisnalar atmak, {x = find ()} catch (RecordNotFound e) {// do stuff} türünde gerçekten çirkin bir koda yol açar.
quant_dev

Boş listeleri döndürmek iyi bir çözümdür, ancak yalnızca yöntem listeleri döndürebilecek bir bağlamda olduğunda. "FindById" durumları için null döndürmeniz gerekir. RecordNotFound istisnalarını sevmiyorum.
Thilo

Demek ki farklılığımızın özü bu. Gözlerime göre x = find (); eğer (x = null) {iş} başka {şeyler yap} ve yakalamaya çalış. Ve gerekirse, kod doğruluğu için güzelliği feda etmeye hazırım. Hayatımda çok sık, dönüş değerlerinin kontrol edilmediği kodlarla karşılaşıyorum.
djna

1

Bazen, NULL döndürmek yapılacak doğru şeydir, ancak özellikle farklı tür dizilerle (diziler, listeler, dizeler, neye sahipseniz) uğraşırken sıfır uzunlukta bir dizi döndürmek muhtemelen daha iyidir. daha kısa ve umarız daha anlaşılır koda yol açarken, API uygulayıcısı adına çok fazla yazı yazmaz.



1

Bu iş parçacığının arkasındaki temel fikir, savunma amaçlı programlamaktır. Yani beklenmeyene karşı kodlayın. Bir dizi farklı yanıt var:

Adamski , bu öneriye verilen yanıtla birlikte Boş Nesne bakmayı öneriyor.

Michael Valenty ayrıca geliştiriciye ne beklenebileceğini anlatmak için bir adlandırma kuralı önerir. ZeroConcept , , düzgün bir şekilde kullanılmasını önerir. Ve diğerleri.

Her zaman savunmacı programlama yapmak istediğimiz "kuralı" koyarsak, bu önerilerin geçerli olduğunu görebiliriz.

Ancak 2 geliştirme senaryomuz var.

Bir geliştirici tarafından "yazılan" sınıflar: Yazar

Başka (belki) geliştirici tarafından "tüketilen" sınıflar: Geliştirici

Bir sınıfın dönüş değeri olan yöntemler için NULL döndürüp döndürmediğine bakılmaksızın, Geliştiricinin nesnenin geçerli olup olmadığını test etmesi gerekecektir.

Geliştirici bunu yapamazsa, o Sınıf / yöntem deterministik değildir. Yani, nesneyi elde etmek için "yöntem çağrısı", "reklamını yaptığı" şeyi yapmazsa (örneğin getEmployee) sözleşmeyi bozmuştur.

Bir sınıfın yazarı olarak, bir yöntem oluştururken her zaman nazik ve savunmacı (ve determinist) olmak isterim.

Dolayısıyla, NULL veya NULL OBJECT'in (örn. (NullEmployee.ISVALID olarak çalışan)) kontrol edilmesi gerektiği ve bunun bir Çalışan koleksiyonunda gerçekleşmesi gerekebileceği düşünüldüğünde, boş nesne yaklaşımı daha iyi bir yaklaşımdır.

Ama aynı zamanda Michael Valenty'nin null döndürmesi ZORUNLU yöntemi isimlendirme önerisini de seviyorum , örneğin getEmployeeOrNull.

Bir istisna atan Yazar, geliştiricinin nesnenin geçerliliğini test etme seçeneğini kaldırıyor; bu, bir nesneler koleksiyonunda çok kötüdür ve geliştiriciyi, tüketen kodlarını dallandırırken istisna işlemeye zorlar.

Dersi tüketen bir geliştirici olarak, umarım yazar bana sınıflarının / yöntemlerinin karşılaşabileceği boş durumdan kaçınma veya program yapma yeteneği verir.

Bu yüzden bir geliştirici olarak NULL'a karşı bir yöntemle savunma amaçlı programlama yapardım. Yazar bana her zaman bir nesne döndüren (BOŞ NESNE her zaman verir) bir sözleşme verdiyse ve bu nesnenin, nesnenin geçerliliğini test etmek için bir yöntemi / özelliği varsa, nesneyi kullanmaya devam etmek için bu yöntemi / özelliği kullanırdım. , aksi takdirde nesne geçerli değil ve onu kullanamam.

Sonuç olarak, Sınıfın / Yöntemlerin Yazarının, bir Geliştiricinin savunma programlarında kullanabileceği mekanizmaları sağlaması gerektiğidir. Yani, yöntemin daha net bir amacı.

Geliştirici, başka bir sınıftan / yöntemden döndürülen nesnelerin geçerliliğini test etmek için her zaman savunmacı programlama kullanmalıdır.

Saygılarımızla

GregJF


0

Bunun diğer seçenekleri şunlardır: başarıyı gösteren veya olmayan (veya bir hata türünü) gösteren bir değer döndürmek, ancak yalnızca başarı / başarısızlık belirtecek bir boole değerine ihtiyacınız varsa, başarısızlık için boş döndürmek ve başarı için bir nesne olmaz daha az doğru olmak, sonra doğru / yanlış döndürmek ve nesneyi parametre yoluyla almak.
Başka bir yaklaşım, başarısızlıkları belirtmek için istisnayı kullanmak olacaktır, ancak burada - aslında bunun KÖTÜ bir uygulama olduğunu söyleyen çok daha fazla ses var (çünkü istisnaları kullanmak uygun olabilir ancak birçok dezavantaja sahiptir).
Bu yüzden, ben şahsen, bir şeylerin ters gittiğinin göstergesi olarak boş döndürmede ve daha sonra kontrol etmede (gerçekten başarılı olup olmadığınızı bilmek için) kötü bir şey görmüyorum. Ayrıca, yönteminizin NULL döndürmeyeceğini ve daha sonra kodunuzu buna dayandıracağını körü körüne düşünmek, başka, bazen bulunması zor hatalara yol açabilir (ancak çoğu durumda sisteminizi çökertecektir :) 0x00000000 er ya da geç).


0

Karmaşık programların geliştirilmesi sırasında istenmeyen boş işlevler ortaya çıkabilir ve ölü kod gibi, bu tür olaylar program yapılarında ciddi kusurları gösterir.

Boş bir işlev veya yöntem, genellikle bir nesne çerçevesindeki revizyona tabi tutulabilir işlevin veya geçersiz kılınabilen yöntemin varsayılan davranışı olarak kullanılır.

Null_function @wikipedia


0

Elbette yöntemin amacına bağlı ... Bazen daha iyi bir seçim bir istisna atmak olabilir. Her şey duruma göre değişir.


0

Kod şunun gibi bir şeyse:

command = get_something_to_do()

if command:  # if not Null
    command.execute()

Execute () yöntemi hiçbir şey yapmayan bir kukla nesneniz varsa ve uygun durumlarda Null yerine bunu döndürürseniz, Null durumunu kontrol etmeniz gerekmez ve bunun yerine şunları yapabilirsiniz:

get_something_to_do().execute()

Dolayısıyla, burada sorun NULL kontrolü ile istisna arasında değil, arayanın özel olmayan vakaları farklı şekilde (herhangi bir şekilde) ele alması ya da yapmaması arasındadır.


0

Kullanım durumum için yöntemden bir Harita döndürmem ve ardından belirli bir anahtarı aramam gerekiyordu. Ancak boş bir Harita döndürürsem, NullPointerException'a yol açacak ve boş bir Harita yerine boş döndüren çok farklı olmayacak. Ancak Java8'den itibaren İsteğe Bağlı'yı kullanabiliriz . Yukarıdakiler, İsteğe Bağlı konseptin tanıtılmasının tam sebebidir.


-3

İyi günler,

Yeni bir nesne oluşturamadığınızda NULL döndürmek, birçok API için standart uygulamadır.

Neden kötü bir tasarım olduğu hakkında hiçbir fikrim yok.

Düzenleme: Bu, uzun yıllardır kongre olduğu C gibi istisnaların olmadığı diller için geçerlidir.

HTH

'Avahappy,


2
Bir nesne yaratamıyorsanız, gerçekten bir İstisna atmalısınız. Bazı sorguyla eşleşen bir nesne bulamıyorsanız, null döndürmek gitmenin yoludur.
Thilo

@Thilo, bunu C dilinde nasıl yapacağımı göster ve en çok ilgileneceğim.
Rob Wells

@RobWells C, nesne yönelimli bir dil değil, ancak bu soru "oop" olarak etiketlendi
yegor256

@ yegor256 Haklısın. Ve orijinal OOP etiketini kaçırdım. Ancak, BS'nin dediği gibi, C ++ 'da bir sınıf, sadece bazı ek üye işlevlerinin eklendiği ve bazı süslü bellek yönetiminin dahili olarak gerçekleştiği bir yapıdır. Ancak, bir API'nin bir yapı döndürmesi gerekiyorsa, yapıyı oluşturamadığınızda NUL döndürmek genellikle kuraldır.
Rob Wells
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.