Eğer / else ifadeleri davaların azlığı veya onlarla başa çıkma zorluğu ile düzenlenmeli mi?


18

Şu anda yazıyorum bazı kod, böyle bir şey var:

if (uncommon_condition) {
    do_something_simple();
} else {
    do();
    something();
    long();
    and();
    complicated();
}

Bir parçam "Yazıldığı gibi iyi. Basit vakalar önce gitmeli, daha karmaşık vakalar da gitmeli." Ama başka bir bölüm şöyle diyor: "Hayır! elseKod if, ifalışılmadık davalarla elseuğraşmak ve diğer tüm davalarla uğraşmak içindir." Hangisi doğru veya tercih edilir?


4
Koşulların basitliği / anlaşılırlığı ile sipariş verin! Geri kalanı iyimserler, dal tahmincileri ve yeniden düzenleme ile halledilebilir.
Marjan Venema

Bu yüzden büyük paralar alıyoruz: bu zor kararları vermek.

Yanıtlar:


24

Düzen olma olasılıklarına göre düzen. En yaygın, en olası vb. Durumlar önce yapılmalıdır.

"Onlarla başa çıkma zorluğu" örnekte kod yapısı, soyutlama vb. İle ele alınmalıdır. ifMaddelerinizin aynı soyut seviyede olmasını istiyorsunuz .

if ( ! LotteryWinner ) {
    GoToWorkMonday();
} else {
    PlanYearLongVacation();
}

6
Performans için ben olabilir katılıyorum. Ama sonra tekrar, çoğu iyimser ve şube tahmincisi bununla mükemmel şekilde ilgilenebilir. Okunabilirliği için ben belki en olası durum daha az olası bir durumda önemli ölçüde daha fazla çizgiler varsa katılıyorum. Ama bu benim için bir yöntemi kullanmaktan daha erken bir yöntem çıkarma ihtiyacını gösterir not. Şahsen notşartlardan kaçınmaya konsantre olurdum . Anlamak için "pozitif" koşullardan daha fazla bilişsel yük uyandırdıkları kanıtlanmıştır ve kodun okunabilirliği / anlaşılabilirliği için zararlıdır. Bunları yalnızca koruma ifadelerinde kullanma eğilimindeyim.
Marjan Venema

2
@ BremenanVenema, "değil" hakkında görüşünü görebiliyorum. Ama çift negatif gerçek "değil" WTF. Geçen gün kodumuzda buna rastladım doesNotAllowxxFiles = false. Yeterince kötü ama sonra bunu yapınif(! doesNotAllowxxFiles)
radarbob

Evet, çift negatifler, ve ile birleştirilen negatifler ve / veya veya 's (sic!) Ve bir yöntemle birleştirilen negatifler / Ad ile değil, her seferinde beynimi bükün :-)
Marjan Venema

Eğer neler olup bittiğini anlamakta zorlanıyorsanız, sanırım şunun gibi bir şey yapmanın yararlı olduğunu düşünüyorum: simpleBool = (! (complexBool || randomfFlag)) &&! randomFlag
TruthOf42 8:14

2
Guard Cümleleri'nin varlığı dışında, (ortak şartta değil, IF ifadesinin THEN bölümünde her zaman istisnai bir koşula sahip olan) dışında size katılıyorum.
Robert Harvey

5

Okunabilirliği artırmaya çalışın. Bunun bir yolu daha uzun kod bloğunu diğer parçaya yerleştirmektir.

if (s == null)
     // short code
else 
     // long 
     // code
     // block

daha okunabilir

if (s != null)
    // long
    // code
    // block
else
    // short code

2
neden daha okunabilir? İkisi arasında okunabilirlik açısından bir fark görmüyorum
John Demetriou

2
@JohnDemetriou Sonra kısa ise Else daha görünür. İnsanlar önce yapıyı tarar, sonra ona anlam atar. Başka bir kod olmadan bir kod ile farklıdır, bu yüzden başka daha görünür hale getirmek daha anlaşılır. (Diğer şeylerin eşit olması, yağmur

4

Kullanım hakkında duyduğum gibi sabit bir kural yok ama bunu takip ediyorum

if(usual)
{
(more often)
}
else (unusual)
{
(rarely occurring)
}

Ama her ikisi de farklı özelliklere sahip aynı işleve sahipse, daha sonra olağandışı ilk önce normalden sonra gidin, böylece bir talimat kaydedebilirsiniz.


if(x == 0)  // 1
  {x = 1;}  // 2
else
  {x = 2;}  // 3

Yukarıdaki kod montaj kodu için böyle bir şey olacaktır:

1. 000d 837DFC00        cmpl    $0, -4(%ebp)
   0011 7509            jne .L2

2. 0013 C745FC01        movl    $1, -4(%ebp)
   001a EB07            jmp .L3

    .L2:
3.001c C745FC02         movl    $2, -4(%ebp)

        .L3:

İçerideki koşul doğruysa akış 1-> 2 (4 yapı)
İçeride koşul yanlışsa akış 1-> 3'tür (3 yapı)

Bu yüzden, her seferinde bir talimat kaydedebilmemiz için başka bir bölüm ve normal durumda olağandışı veya nadiren meydana gelen olayları koymak daha iyidir ;-)


2

Ben tam ters desen kodunu okumak daha kolay yol açar ve ifadeler iç içe azaltır veya ortadan kaldırır bulduk. Ben buna "dayağı" deseni denir. (Hikaye anlatmada, bir dayağı, son görev tamamlanmadan önce başarılı bir şekilde yerine getirilmesi gereken bir dizi zorluk olacaktır.) Önce kenar davalarınızı ele alarak, kodunuzun ana gövdesinin temiz ve özlü olmasına izin verirsiniz:

if(gauntlet_1){ handle the first gauntlet condition }; 
if(gauntlet_2){ handle the second gauntlet condition };
...
// All preconditions (gauntlets) have been successfully handled

// Perform your main task here

Dolayısıyla, "tutamak dayağı" kısmı ya bir atış ya da geri dönüş ifadesi gibi bir kontrol transferi olmalı ya da hatayı gerçekten düzeltmek zorunda kalacaktı. Bazı insanlar if ... ifadeleri bir dizi kaşlarını çattı, ama ben ve aslında söylediğiniz gibi kodu okumak için kolaylaştırır düşünüyorum ve sanmıyorum.

1
Dayağı koşulu, işlevin başarılı olmasını engelleyecek bir şeyse, hemen bir hata döndürür. Dayağı koşulu ele alınabiliyorsa, bunu mümkün olduğunca ana kod gövdesine girmeden önce yaparım. Öncelikle benim deneyimimde karanlık ve kodlama hatalarını hata ayıklamak birincil nedenlerinden biri olan iç içe IF deyimleri kaçınmaya çalışıyorum.
Byron Jones

0

Benim için yürüttükleri kodun karmaşıklığından çok koşullar hakkında. İlk önce olağandışı koşulları tuzağa düşürmek için daha sonra daha yaygın olanları sipariş etmeniz gerekir. Ayrıca, başka kod gerçekten uzun ve karmaşıksa, koşullu kısmı okuyucu için açık tutmak için muhtemelen bir alt yapardım.


-1

Sabit bir kuralım yok, ama genel olarak bunu takip ediyorum - önce, bunu hesaba katacak kaçırılmış bir tasarım deseninin nerede olduğunu düşünün. Değilse, eğer yazarımın durumu en açık şekilde anlaşılacak şekilde yazarım. Yani, çift negatiflerden ve benzerlerinden kaçınmak.


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.