Czy oświadczenia powinny / powinny być uporządkowane według rzadkości przypadków lub trudności w radzeniu sobie z nimi?

18

W jakimś kodzie, który teraz piszę, mam coś takiego:

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

Część mnie myśli: „W porządku, w jaki jest napisany. Proste sprawy powinny iść na pierwszym miejscu, a bardziej skomplikowane sprawy powinny iść dalej”. Ale inna część mówi: „Nie! elseKod powinien przejść poniżej if, ponieważ ifsłuży do obsługi nietypowych przypadków i elsedo obsługi wszystkich innych przypadków”. Które jest poprawne lub preferowane?

GODŁO
źródło
4
Sortuj według prostoty / zrozumiałości warunków! Resztą mogą zająć się optymalizatorzy, predyktory branżowe i refaktoryzacja.
Marjan Venema
Właśnie dlatego otrzymujemy duże pieniądze: podejmowanie tych trudnych decyzji.

Odpowiedzi:

24

Porządkuj według prawdopodobieństwa wykonania. Najpowszechniejsze, najprawdopodobniej itd. Warunki powinny być pierwsze.

„Trudnością w radzeniu sobie z nimi” powinna zajmować się struktura kodu, abstrakcja itp. W przykładzie blok else mógłby zostać przekształcony w pojedyncze wywołanie metody. Chcesz, aby twoje ifklauzule były na tym samym abstrakcyjnym poziomie.

if ( ! LotteryWinner ) {
    GoToWorkMonday();
} else {
    PlanYearLongVacation();
}
radarbob
źródło
6
Za wykonanie I może zgodzić. Ale z drugiej strony większość optymalizatorów i predyktorów branżowych jest w stanie doskonale sobie z tym poradzić. Dla czytelności I może zgodzić jeśli najprawdopodobniej sprawa ma znacznie więcej linii niż mniej prawdopodobnym przypadku. Ale dla mnie oznaczałoby to wcześniej potrzebę wyodrębnienia metody niż użycia metody not. Osobiście koncentrowałbym się na unikaniu notwarunków. Udowodniono, że powodują więcej obciążenia poznawczego do zrozumienia niż „pozytywne” warunki i są szkodliwe dla czytelności / zrozumiałości kodu. Zwykle używam ich tylko w oświadczeniach ochronnych.
Marjan Venema
2
@MarjanVenema, widzę twój punkt widzenia na temat „nie” ing. Ale podwójny minus to prawdziwy „nie” WTF. Pewnego dnia natknąłem się na to w naszym kodzie doesNotAllowxxFiles = false. Wystarczająco źle, ale zrób toif(! doesNotAllowxxFiles)
radarbob
Tak, podwójne negatywy, negatywy połączone z i / lub i / lub sic (sic!) I negatywy połączone z metodą / var z Not in name, wprawiają mnie w zakręt za każdym razem :-)
Marjan Venema
jeśli masz problem ze zrozumieniem, co się dzieje, myślę, że często przydatne jest zrobienie czegoś takiego: simpleBool = (! (complexBool || randomfFlag)) &&! randomFlag
TruthOf42
2
Zgodziłbym się z tobą, z wyjątkiem istnienia klauzul ochronnych (które zawsze mają wyjątkowy warunek w TO, część instrukcji IF, a nie ogólny warunek).
Robert Harvey
5

Spróbuj poprawić czytelność. Jednym ze sposobów jest umieszczenie dłuższego bloku kodu w innej części.

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

jest bardziej czytelny niż

if (s != null)
    // long
    // code
    // block
else
    // short code
CWallach
źródło
2
dlaczego jest bardziej czytelny? Nie widzę żadnej różnicy między nimi pod względem czytelności
John Demetriou
2
@JohnDemetriou Inna jest bardziej widoczna, jeśli wtedy jest krótki. Ludzie najpierw szukają struktury, a następnie przypisują jej znaczenie. Kod bez Else różni się od kodu z jednym, więc zwiększenie widoczności Else jest bardziej zrozumiałe. (Wszystkie inne rzeczy są równe, we wtorki, gdy nie pada itp.)
4

Żadnej ustalonej reguły jako takiej nie słyszałem o użyciu, ale postępuję w ten sposób

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

Ale jeśli oba mają tę samą funkcję z różnymi właściwościami, lepiej najpierw wybrać nietypowe niż zwykle, aby można było zapisać jedną instrukcję.


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

Dla powyższego kodu kod zestawu będzie mniej więcej taki:

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:

Jeśli warunek w środku jest prawdą, wówczas przepływ wynosi 1-> 2 (4 intruzów)
JEŻELI warunek w środku, jeśli jest fałszywy, wówczas przepływ wynosi 1-> 3 (3 intruzji)

Lepiej więc umieścić nietypowe lub rzadko występujące zdarzenia w części lub normalnym stanie w innym, abyśmy mogli zapisać jedną instrukcję za każdym razem ;-)

Santosh Mudhol
źródło
2

Przekonałem się, że dokładnie przeciwny wzorzec prowadzi do łatwiejszego odczytu kodu i zmniejsza lub eliminuje zagnieżdżone instrukcje if. Nazywam to wzorcem „rękawicy”. (W opowiadaniu historii rękawica byłaby serią wyzwań, które należy spełnić przed ukończeniem ostatecznego zadania.) Najpierw zajmując się przypadkami krawędziowymi , pozwalasz, aby główna część kodu była czysta i zwięzła:

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
Byron Jones
źródło
Tak więc część „uchwyt rękawicy” musiałaby albo być przekazaniem kontroli, jak instrukcja rzutowania lub powrotu, albo musiałaby faktycznie naprawić błąd. Niektórzy ludzie krzywo patrzą na serię instrukcji if ... return, ale ja nie i myślę, że w rzeczywistości ułatwia to odczytanie kodu, jak powiedziałeś.
1
Jeśli warunek rękawicy jest czymś, co uniemożliwi działanie tej funkcji, natychmiast zwraca błąd. Jeśli można sobie poradzić ze stanem rękawicy, robię to przed wprowadzeniem głównej części kodu, gdy tylko jest to możliwe. Staram się przede wszystkim unikać zagnieżdżonych instrukcji IF, które z mojego doświadczenia są jedną z głównych przyczyn niejasnych i trudnych do debugowania błędów kodowania.
Byron Jones,
0

Dla mnie chodzi bardziej o warunki niż o złożoność wykonywanego kodu. Musisz uporządkować warunki, aby najpierw uwięzić nietypowe, a potem bardziej powszechne. Ponadto, jeśli kod else jest naprawdę długi i skomplikowany, prawdopodobnie stworzyłbym do tego napis, aby uwidocznić część warunkową dla czytelnika.

Steve Thomas
źródło
-1

Nie mam ustalonej reguły, ale generalnie ją przestrzegam - najpierw zastanów się, gdzie jest pominięty wzorzec projektowy, który to uwzględni. Jeśli nie, piszę to, aby warunek w if był jak najbardziej zrozumiały. To znaczy, unikając podwójnych negatywów i tym podobnych.

Don Branson
źródło