2011-02-10 5 views
5

내가 잠재적으로 세트를 가지고 다음과 같이 if 문 : 모든 가능한 순열에 대한거대한 if 문 - 디자인 패턴을 단순화 하시겠습니까?

if (a and b and c and d) { 
    // do stuff 
} else (!a and b and c and d) { 
    // do something else 
} else (!a and !b and c and D) { 
    // do yet something else 
} ... 

등등.

는 내가이 일을 생각 :

switch ((a ? 'Y' : 'N') . (b ? 'Y' : 'N') . (c ? 'Y' : 'N') . (d ? 'Y' : 'N')) { 

    case 'YNYN': 
    // do stuff 
    break; 

    case 'NNNN': 
    // etc. 
    break; 

} 

더 좋은 방법이 있나요?

+4

if 문이 적게 사용합니다. 진심으로,이 질문은 너무 모호합니다 –

+1

스위치를 사용하지 마십시오. –

+2

나는 여기에서'and'가 (스위치 내부에서) 작동하지 않을 것이라고 생각합니다. '.'을 사용 하시겠습니까? http : // 코드 패드.org/X4fIQsSz – Dogbert

답변

0

다른 노드가 가능한 끝 상태 인 의사 결정 트리를 사용하여이 문제를 해결해야한다고 생각합니다. 그러면 트리에서 문제를 구성하고 이러한 모든 문제를 해결할 수 있습니다. ...

0

일련의 조건을 기반으로 데이터를 집계해야 할 때 한 번 비슷한 사례를 취 했으므로, 그 중 5 개의 스위치가 켜져 있거나 꺼져있을 수 있습니다.

정상적인 상황에 대한 정보를 취합하여 다루기 위해서는 실제로 사용 된 상황이 아닌 n^2 다른 동작이있는 경우 여러 if 문을 사용해야합니다. 실제로 많은 순열이 없다면, 같은 결과를 묶어서 if의 수를 줄이십시오.

0

예, 더 좋은 방법이 있습니다.

오, 그보다 더 자세히 알고 싶습니까? 네 변수가있는 일종의 진리표가있는 것 같습니다. 가능한 결과 (2^4)가 있습니까? 아니면 하위 집합에만 관심이 있습니까? 대략적으로 같은 수의 결과를 가진 변수가 하나있는 경우,이를 가장 많이 사용되는 if 문으로 사용하고 중첩 된 if를 사용하십시오.

if (b) { 
    // cases where b is true 
    if (...) 
    ... 
} else { 
    // cases where b is false 
    if (...) 
    ... 
} 

또한 switch 문을 사용할 수도 있지만 Y 및 N으로 구성된 문자열은 비트 필드를 사용할 수 없습니다.

7

각 상태에 대해 일련의 클래스를 작성하면됩니다 (구체적으로 알지 못함). 그리고 그 클래스 위에 doStuff를 밀어 :

class DoStuff { //The Client 
    protected $strategies = array(); 
    public function addStrategy(iDoStuffStrategy $strategy) { 
     $this->strategies[] = $strategy; 
    } 
    public function doStuff ($a, $b, $c, $d) { 
     foreach ($this->strategies as $strategy) { 
      if ($strategy->test($a, $b, $c, $d)) { 
       return $strategy->doStuff(); 
      } 
     } 
     throw new RuntimeException('Unhandleable Situation!'); 
    } 
} 

interface iDoStuffStrategy { 
    // Return a bool if you can handle this situation 
    public function test($a, $b, $c, $d); 
    // Execute the implementation 
    public function doStuff(); 
} 

그런 다음, 각 클래스는 다음과 같이 보일 것이다 :

public function StrategyFoo implements iDoStuffStrategy { 
    public function test($a, $b, $c, $d) { 
     return $a && $b && $c && $d; 
    } 
    public function doStuff() { 
     //DoStuff! 
    } 
} 
public function StrategyBar implements iDoStuffStrategy { 
    public function test($a, $b, $c, $d) { 
     return !$a && $b && $c && $d; 
    } 
    public function doStuff() { 
     //DoStuff! 
    } 
} 

그것은 기본적으로 Strategy Pattern의 구현입니다. 그렇게하면 의사 결정 트리를 분리 할 수 ​​있습니다.

+0

+1이 접근법이나 이와 유사한 것이 무엇을 요구합니다. 언제든지 스위치 문이 길어질 때마다 더 많은 OOP 스타일 사고를 사용하는 것이 가장 좋습니다. – NotMe

+0

@ircmaxwell ... 나는이 코드의 버전을 사용하려고 노력 중이며 뭔가 놓친다면 궁금하다. 'addStrategy' 메쏘드는 어떻게 객체들을'$ strategy' 변수에 추가합니까? 나는이 디자인 패턴을 정말 좋아하고 그것을 구현하고 싶지만, 나는 그 부분을 작동시키지 못한다. – tollmanz

0

나는 네 개의 부 울린을 4 비트로 처리 할 것이므로 0과 15 사이의 정수로 표현할 것이다. 나는 16 개의 요소를 가진 배열을 만들고 배열의 각 요소에 함수 포인터를 저장한다. 당신이 이것을 할 필요가있을 때마다, 나는 부울을 비트 패턴으로 평가하고, int로 변환하고, 배열의 해당 인덱스에 저장된 메소드를 호출합니다.

나는 당신이 PHP에 대해 묻고있는 것을 알고 있는데, 나는 그것이 모를 까봐 두렵다. C#에서는 다음과 같이 할 수 있습니다.

static class Multiplexer 
{ 
    public static string Multiplex(bool a, bool b, bool c, bool d) 
    { 
     var i = 0; 
     i |= (a ? 1 : 0) << 3; 
     i |= (b ? 1 : 0) << 2; 
     i |= (c ? 1 : 0) << 1; 
     i |= (d ? 1 : 0); 
     return _functions[i](); 
    } 

    private static Func<string>[] _functions = new Func<string>[] { 
     () => { return "pie";}, 
     () => { return "index 1"; }, 
     () => { return DateTime.Now.ToString(); }, 
     () => { return "pie";}, 
     () => { return "index 1"; }, 
     () => { return DateTime.Now.ToString(); }, 
     () => { return Assembly.GetExecutingAssembly().FullName; }, 
     () => { return ""; }, 
     () => { return "pie";}, 
     () => { return "index 1"; }, 
     () => { return DateTime.Now.ToString(); }, 
     () => { return "pie";}, 
     () => { return "index 1"; }, 
     () => { return DateTime.Now.ToString(); }, 
     () => { return Assembly.GetExecutingAssembly().FullName; }, 
     () => { return ""; }}; 
}