여러 if-else에서 플래그를 처리하는 방법


10

나는 이것을 내 코드와 다른 사람들에게서 충분히 자주 본 것 같습니다. 그것에 대해 끔찍하게 잘못 된 것은 아무것도 없지만 더 잘 할 수있는 것처럼 보이기 때문에 나를 귀찮게합니다. 나는 사례 진술을 가정하고 조금 더 이해가 될 수 있지만 종종 변수는 사례 진술 (언어에 따라 다름)에서 제대로 작동하지 않거나 전혀 작동하지 않는 유형입니다.

If variable == A
    if (Flag == true)
        doFooA()
    else
        doFooA2

else if variable == B
    if (Flag == true)
        doFooB()
    else
        doFooB2
else if variable == C
    if (Flag == true)
        doFooC()
    else
        doFooC2

플래그 == true 일 때 하나의 세트가 처리되는 if-elses의 2 세트와 같이 이것을 "인수 화"하는 여러 가지 방법이있는 것 같습니다.

이것을 고려하는 "좋은 방법"이 있습니까, 아니면이 if-else 알고리즘이 발생할 때 일반적으로 무언가 잘못하고 있다는 것을 의미합니까?


6
플래그 변수를 doFooX에 전달하여 플래그 자체를 처리 할 수 ​​있습니까?
Jean-François Côté 2016 년

하지만 플래그가 참인지 평가 한 다음 doFooX1 또는 doFooX2를 수행하는 doFooX 메소드가 있습니다.
TruthOf42

5
IMHO, 여전히 명확하게 읽을 수 있습니다. 그렇다면 그것은 doFooA와 doFooA2가 무엇을하는지에 달려 있습니다.
Jean-François Côté

2
if (Flag == true)그냥 쓰는 것이 아니라 쓰는가 If (Flag)? 그것이 If (Flag == true)더 좋다고 생각하면 if ((Flag == true) == true)어떻습니까?
Keith Thompson

1
아래의 대부분의 답변에서 가장 중요한 것은 논리적 흐름과 미래의 코드 유지와 관련하여 영리한 트릭보다 단순성과 가독성이 훨씬 중요하다는 것 입니다.
Patrick Hughes

답변:


18

다형성으로 처리 할 수 ​​있습니다.

factory(var, flag).doFoo();

if / else가 무언가의 유형을 검사 할 때마다 팩토리 메소드에서 if / else 검사를 중앙 집중화 한 다음 doFoo ()를 다형성으로 호출하는 것을 고려할 수 있습니다. 그러나 이것은 일회성 솔루션으로 과잉 살 수 있습니다.

키가 var / flag이고 키가 함수 자체 인 키 / 값 맵을 만들 수 있습니다.

do[var, flag]();

2
+1 : 거의 항상 테이블 조회가 중첩 된 if 문을 이깁니다.
케빈 클라인

1
이것이 최선의 해결책이라고 말하고 싶습니다.
머핀 남자

6

여러 개의 중첩 된 if는 코드의 순환 복잡성을 증가시킵니다. 최근까지 함수에 여러 개의 종료 점이 있으면 구조화 된 코드가 잘못 처리되었지만 코드가 단순하고 짧기 만하면 코드를 쉽게 읽을 수 있습니다.

    if (variable == A && Flag) {
        doFooA();
        return;
    }

    if (variable == A) {
        doFooA2();
        return;
    }

    if (variable == B && Flag){
        doFooB();
        return;
    }

    if (variable == B){
        doFooB2();
        return;
    }

    if (variable == C && Flag){
         doFooC();
         return;
    }

    if (variable == C){
         doFooC2();
    }

    return;

3

또 다른 옵션은 if와 switch를 결합하는 것입니다. 중첩 된 if 기술보다 우수하지는 않지만 중복 테스트 수를 줄일 수 있습니다 (스위치가 점프 테이블에 최적화 된 경우).


if (flag)
{
    switch (variable)
    {
        case A:
           ... blah
           break;

        case B:
           ... blah
           break;

        case C:
           ... blah
           break;

        default:
           ... log an error.
           ... maybe do a default action.
           break;
    }
}
else // flag == false
{
    switch (variable)
    {
        case A:
           ... blah
           break;

        case B:
           ... blah
           break;

        case C:
           ... blah
           break;

        default:
           ... log an error.
           ... maybe do a default action.
           break;
}

0

글쎄, 항상이 ...

if variable == A && Flag
    doFooA()
else if variable == A 
    doFooA2    
else if variable == B && Flag
    doFooB()
else if variable == B
    doFooB2
else if variable == C && Flag
     doFooC()
else if variable == C
     doFooC2

그러나 솔직히 원래 코드는 처음에는 나쁘지 않다고 생각합니다.


0

다형성 및 rule배열 사용

interface IRule() {
  boolean applicable(args...);
  obj apply(args...);
}

static final Array<IRule> rules = [new MeaningfulNameRule1(), new MeaningfulNameRule2(), ...];

/* where */
class MeaningfulNameRuleX extends IRule{ /* */ }

/* In your method */

for (rule in rules) {
  if (rule.applicable(a,b,c)){
    return rule.apply(e,f,g);
  }
}

또는 mike30제안 된대로 : 규칙 조건이 쉽게 키를 형성 할 수 있다면 해시 맵이 가장 좋은 방법입니다.

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