드문 경우 나 처리하기 어려운 경우에 대비하여 진술해야합니까?


18

현재 작성중인 일부 코드에는 다음과 같은 것이 있습니다.

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

저의 일부는 "제작 된 방식은 괜찮습니다. 간단한 경우는 먼저 가고 더 복잡한 경우는 다음에 가야합니다"라고 생각합니다. 그러나 또 다른 부분은 "아니오! else코드는 예외적 인 경우 를 다루기위한 것이고 다른 모든 경우를 다루기위한 if것이므로 코드 아래에 가야한다 "고 말합니다 . 어느 것이 정확하거나 선호됩니까?ifelse


4
조건의 단순성 / 이해성으로 주문하십시오! 나머지는 옵티 마이저, 분기 예측기 및 리팩토링으로 처리 할 수 ​​있습니다.
Marjan Venema

이것이 어려운 결정을 내리기 위해 우리가 큰 돈을 지불하는 이유입니다.

답변:


24

실행 가능성에 따라 주문하십시오. 가장 흔하고 가장 가능성이 높은 조건이 먼저 진행됩니다.

예제에서 "처리 어려움"은 코드 구조, 추상화 등에 의해 처리되어야하며 else 블록은 단일 메소드 호출로 리팩토링 될 수 있습니다. 당신은 당신의 if절이 동일한 추상 수준에 있기를 원합니다 .

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

6
성능을 위해 내가 할 수 동의합니다. 그러나 대부분의 옵티 마이저와 브랜치 예측자는이를 완벽하게 처리 할 수 ​​있습니다. 가독성을 위해 가장 가능성이 높은 사례가 가능성이 적은 경우보다 훨씬 더 많은 행을 가지고 있는지에 동의 할 수 있습니다 . 그러나 나에게 그것은을 사용하는 것보다 방법을 추출해야한다는 것을 빨리 나타냅니다 not. 개인적으로 나는 not조건 을 피하는 데 집중할 것 입니다. 그것들은 "긍정적 인"조건보다 이해하기에 더 많은인지 적 부하를 유발하는 것으로 입증되었으며 코드의 가독성 / 이해성에 해 롭습니다. 나는 경비 진술에만 사용하는 경향이 있습니다.
Marjan Venema

2
@MarjanVenema, "하지"에 대한 요점을 볼 수 있습니다. 그러나 이중 부정은 실제 "비"WTF입니다. 다른 날에는 코드에서이 문제가 발생했습니다 doesNotAllowxxFiles = false. 충분히 if(! doesNotAllowxxFiles)
나쁘지만

네, 더블 네거티브, 네가티브 및 / 또는 (또는 Sic!)와 네거티브가 결합 된 네거티브와 이름이없는 방법 / var과 네거티브가 결합 된 경우, 매번 내 뇌를
뒤틀리게합니다

무슨 일이 일어나고 있는지 이해하는 데 어려움이 있다면, 다음과 같은 일을하는 것이 종종 유용하다고 생각합니다. simpleBool = (! (complexBool || randomfFlag)) &&! randomFlag
TruthOf42

2
Guard Clauses (공통 조건이 아니라 IF 문의 THEN 부분에 항상 예외적 인 조건이 있음)가 있다는 점을 제외하고는 귀하에게 동의합니다.
Robert Harvey

5

가독성을 향상 시키십시오. 한 가지 방법은 더 긴 코드 블록을 else 부분에 배치하는 것입니다.

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

보다 읽기 쉽다

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

2
더 읽기 쉬운 이유는 무엇입니까? 나는 가독성의 측면에서 둘 사이의 차이 볼
존 데 메트

2
@JohnDemetriou Then이 짧으면 Else가 더 잘 보입니다. 사람들은 먼저 구조를 스캔 한 다음 의미를 부여합니다. Else가없는 코드는 하나가있는 코드와 다르므로 Else를 더 잘 보이게 만드는 것이 더 이해하기 쉽습니다. (이 등, 비가되지 않을 때 다른 모든 조건이 화요일에, 동일한 것)

4

사용법에 대해 들었던 고정 규칙이 없지만 다음과 같이 따릅니다.

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

그러나 둘 다 다른 속성을 가진 동일한 기능을 가지고 있다면 평범하지 않은 첫 번째 명령을 저장하는 것이 좋습니다.


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

위의 코드 어셈블리 코드는 다음과 같습니다.

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:

내부 조건이 참인 경우 흐름은 1-> 2 (4 intructions) 인
경우 내부 조건이 거짓 인 경우 흐름은 1-> 3 (3 intructions)입니다.

따라서 매번 하나의 명령을 저장할 수 있도록 비정상적이거나 드물게 발생하는 이벤트를 다른 부분과 정상적인 조건에 넣는 것이 좋습니다.


2

나는 정반대의 패턴으로 코드를 쉽게 읽을 수 있으며 중첩 된 if 문을 줄이거 나 없앤다는 것을 알았습니다. 이것을 "건틀릿"패턴이라고합니다. (이야기에서, 건틀릿은 최종 작업이 완료되기 전에 성공적으로 해결해야 할 일련의 도전이 될 것입니다.) 가장 먼저 처리해야 할 사항은 코드의 본문을 깨끗하고 간결하게하는 것입니다.

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

따라서 "핸들 건틀릿"부분은 throw 또는 return 문과 같은 제어의 전송이거나 결함을 실제로 수정해야합니다. 어떤 사람들은 일련의 if ... return 문에 눈살을 찌푸 리지만 실제로는 코드가 읽기 쉽다고 생각하지 않습니다.

1
건틀릿 조건이 함수의 성공을 방해하는 것이면 즉시 오류를 리턴합니다. 건틀릿 조건을 처리 할 수 ​​있으면 가능한 한 코드 본문에 들어가기 전에 처리합니다. 나는 주로 중첩 된 IF 문을 피하려고 노력하고 있는데, 내 경험상 코딩 오류가 모호하고 디버깅하기 어려운 주요 원인 중 하나입니다.
바이런 존스

0

나에게 그것은 그들이 실행하는 코드의 복잡성보다 조건에 관한 것입니다. 비정상적인 조건을 먼저 포착 한 다음에 더 일반적인 조건을 포착하려면 조건을 주문해야합니다. 또한 else 코드가 실제로 길고 복잡하다면 독자에게 조건부 부분을 분명하게 유지하기 위해 하위 코드를 만들 것입니다.


-1

나는 정해진 규칙이 없지만 일반적으로 이것을 따릅니다. 먼저 이것을 무시할 디자인 패턴이 누락 된 부분을 고려하십시오. 그렇지 않은 경우 if의 조건이 가장 명확하게 이해되도록 작성합니다. 즉, 이중 네거티브 등을 피하십시오.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.