Pytanie Najlepszy sposób na sformatowanie instrukcji o wielu warunkach


Jeśli chcesz kod do wykonania na podstawie dwóch lub więcej warunków, który jest najlepszym sposobem sformatowania tego, jeśli instrukcja?

pierwszy przykład: -

if(ConditionOne && ConditionTwo && ConditionThree)
{
   Code to execute
}

Drugi przykład: -

if(ConditionOne)
{
   if(ConditionTwo )
   {
     if(ConditionThree)
     {
       Code to execute
     }
   }
}

co jest najłatwiejsze do zrozumienia i przeczytania, biorąc pod uwagę, że każdy warunek może być długą nazwą funkcji lub czegoś.


76
2017-10-31 10:15


pochodzenie




Odpowiedzi:


Wolę opcję A

bool a, b, c;

if( a && b && c )
{
   //This is neat & readable
}

Jeśli masz szczególnie długie parametry zmiennych / metod, możesz je po prostu przerwać

if( VeryLongConditionMethod(a) &&
    VeryLongConditionMethod(b) &&
    VeryLongConditionMethod(c))
{
   //This is still readable
}

Jeśli są jeszcze bardziej skomplikowane, rozważam wykonanie metod warunkowych oddzielnie poza instrukcją if

bool aa = FirstVeryLongConditionMethod(a) && SecondVeryLongConditionMethod(a);
bool bb = FirstVeryLongConditionMethod(b) && SecondVeryLongConditionMethod(b);
bool cc = FirstVeryLongConditionMethod(c) && SecondVeryLongConditionMethod(c);

if( aa && bb && cc)
{
   //This is again neat & readable
   //although you probably need to sanity check your method names ;)
}

IMHO Jedynym powodem dla opcji "B" byłoby oddzielenie else funkcje do uruchomienia dla każdego warunku.

na przykład

if( a )
{
    if( b )
    {
    }
    else
    {
        //Do Something Else B
    }
}
else
{
   //Do Something Else A
}

112
2017-10-31 10:20



Lubię to. Chociaż nie jestem wielkim fanem idei metody, chyba że metody już istnieją i zwracają wartość boolowską. - Thomas Owens
+1 dla nazw metod sprawdzania poprawności - Aidan Miles
Czy w drugim przykładzie nie oceniasz wszystkiego bez powodu? - Odys


Inne odpowiedzi wyjaśniają, dlaczego pierwsza opcja jest zwykle najlepsza. Ale jeśli masz wiele warunków, rozważ utworzenie osobnej funkcji (lub właściwości), sprawdzając warunek w opcji 1. To sprawia, że ​​kod jest znacznie łatwiejszy w odczytaniu, przynajmniej przy użyciu dobrych nazw metod.

if(MyChecksAreOk()) { Code to execute }

...

private bool MyChecksAreOk()
{ 
    return ConditionOne && ConditionTwo && ConditionThree;
}

Warunki zależą tylko od lokalnych zmiennych zasięgu, możesz uczynić nową funkcję statyczną i przekazać wszystko, czego potrzebujesz. Jeśli jest miks, podaj lokalne rzeczy.


27
2017-10-31 10:20



Stwierdziłem, że jest to najskuteczniejsze i łatwiejsze do dodania warunki później - pbojinov
+1 doskonała sugestia! - R Thiede
+1 najpierw podniosłem brwi, ale to naprawdę jest najlepsza odpowiedź imho. o tym boolean isOkToDoWhatever jako własność ma wiele sensu. - grinch
funkcje są dobre dla abstrakcji logiki, wykorzystuj je! - loujaybee
Ale to po prostu przesuwa ten sam złożony warunek gdzie indziej również musi być czytelny więc wracamy do tego pierwszego. Nie chodzi tylko o ifczytelność oświadczenia, ale raczej czytelność warunku. - Robert Koritnik


Pierwszy przykład jest bardziej "łatwy do odczytania".

Właściwie, moim zdaniem powinieneś używać drugiego tylko wtedy, gdy musisz dodać "logikę innego", ale w przypadku prostego warunkowego użyj pierwszego smaku. Jeśli obawiasz się długiego stanu, zawsze możesz użyć następnej składni:

if(ConditionOneThatIsTooLongAndProbablyWillUseAlmostOneLine
                 && ConditionTwoThatIsLongAsWell
                 && ConditionThreeThatAlsoIsLong) { 
     //Code to execute 
}

Powodzenia!


9
2017-10-31 10:23





Zadano pytanie, na które, jak dotąd, odpowiedziano, że decyzja powinna być podejmowana wyłącznie na podstawie "syntaktycznej".

Powiedziałbym, że to właściwa odpowiedź, w jaki sposób określa się szereg warunków w powinni także polegać na "semantykach". Warunki powinny być rozbite i zgrupowane zgodnie z tym, co razem idzie "koncepcyjnie".

Jeśli dwa testy są naprawdę dwiema stronami tej samej monety, np. jeśli (x> 0) && (x <= 100), umieść je razem w tym samym wierszu. Jeśli inny warunek jest koncepcyjnie daleki odległy, np. user.hasPermission (Admin ()), a następnie umieść go na własnej linii

Na przykład.

if user.hasPermission(Admin()) {
   if (x >= 0) && (x < 100) {
      // do something
   }
}

7
2017-10-31 11:07





Drugi to klasyczny przykład Strzałkowy anty-wzór Więc unikam tego ...

Jeśli twoje warunki są zbyt długie, wyodrębnij je do metod / właściwości.


4
2017-10-31 10:46





Pierwszy jest łatwiejszy, ponieważ, jeśli przeczytasz go od lewej do prawej, otrzymasz: "Jeśli coś I coś tam I TO coś tam", co jest łatwym do zrozumienia zdaniem. Drugi przykład brzmi: "Jeśli coś TO, jeśli coś jest TO, jeśli coś innego TO", co jest niezgrabne.

Zastanów się też, czy w klauzuli chciałbyś użyć niektórych OR - w jaki sposób zrobiłbyś to w drugim stylu?


3
2017-10-31 10:16





    if (   ( single conditional expression A )
        && ( single conditional expression B )
        && ( single conditional expression C )
       )
    {
       opAllABC();
    }
    else
    {
       opNoneABC();
    }

Formatting a multiple conditional expressions in an if-else statement this way:
1) allows for enhanced readability:
    a) all binary logical operations {&&, ||} in the expression shown
       first
    b) both conditional operands of each binary operation are obvious
       because they align vertically
    c) nested logical expressions operations are made obvious using
       indentation, just like nesting statements inside clause
2) requires explicit parenthesis (not rely on operator precedence rules)
    a) this avoids a common static analysis errors
3) allows for easier debugging
    a) disable individual single conditional tests with just a //
    b) set a break point just before or after any individual test
    c) e.g. ...

    // disable any single conditional test with just a pre-pended '//'
    // set a break point before any individual test
    // syntax '(1 &&' and '(0 ||' usually never creates any real code
    if (   1
        && ( single conditional expression A )
        && ( single conditional expression B )
        && (   0
            || ( single conditional expression C )
            || ( single conditional expression D )
           )
       )
    {
       ... ;
    }

    else
    {
       ... ;
    }

3
2018-04-19 22:01





wierzę switch...case oświadczenie jest najlepszym sposobem napisania czystego kodu w tych okolicznościach, jeśli język programowania go obsługuje.

switch (//variable or Boolean) {
  case //Condition A:
  case //Condition B:
  case //Condition C:
    //Code to execute;
}

2
2017-12-03 07:38



To może być miłe, ale usuwa "zaletę" oceny "zwarcia" / leniwego. - TheLibrarianCz


W Perlu można to zrobić:

{
  ( VeryLongCondition_1 ) or last;
  ( VeryLongCondition_2 ) or last;
  ( VeryLongCondition_3 ) or last;
  ( VeryLongCondition_4 ) or last;
  ( VeryLongCondition_5 ) or last;
  ( VeryLongCondition_6 ) or last;

  # Guarded code goes here
}

Jeśli któryś z warunków się nie powiedzie, będzie on kontynuowany po bloku. Jeśli definiujesz jakieś zmienne, które chcesz zachować po bloku, będziesz musiał zdefiniować je przed blokiem.


0
2017-10-31 23:14



To wygląda Perlish - w "robi to CO?" sens;) Ale jest naprawdę czytelny, kiedy już się przyzwyczaisz. - Piskvor


Gdy warunek jest bardzo skomplikowany, używam następującego stylu (przykład z życia w PHP):

if( $format_bool &&
    (
        ( isset( $column_info['native_type'] )
            && stripos( $column_info['native_type'], 'bool' ) !== false
        )
        || ( isset( $column_info['driver:decl_type'] )
            && stripos( $column_info['driver:decl_type'], 'bool' ) !== false
        )
        || ( isset( $column_info['pdo_type'] )
            && $column_info['pdo_type'] == PDO::PARAM_BOOL
        )
    )
)

Uważam, że jest bardziej ładny i czytelny niż zagnieżdżanie wielu poziomów if(). W niektórych przypadkach po prostu nie można podzielić złożonego stanu na części, ponieważ w przeciwnym razie trzeba będzie powtórzyć te same instrukcje if() {...} blokuj wiele razy.

Uważam też, że dodanie "powietrza" do kodu jest zawsze dobrym pomysłem. Znacznie poprawia czytelność.


-1
2018-02-21 10:57