2017-01-23 5 views
0

나는 나의 첫 번째 asp.net mvc 웹 응용 프로그램에서 일하고있다. 나는 14 개 주에있을 수있는 양식을 가지고 있으며 현재 상태에 따라 다른 주로의 전환이 가능하거나 불가능합니다. 각 현재 상태에 대해 평균 3-5 가지 차이가 ​​가능합니다.상태 머신 내장 스위치

지금해야 할 일은 일부 상태 전환 중에 트리거 동작입니다. 초기 상태 및 최종 상태에 따라 일부 작업이 처리됩니다 (예 : 전자 메일 전송).

내가 스위치 문을 사용하여이 작업을 시작 :
switch ((int)currentState) 
     { 
      //Initial 
      case -1: 
       { 
        switch ((int)nextState) 
        { 
         //Next state: Inv. is waiting 
         case 1: 
          { 
           //Send email to x 
           emailHelper.Send(x,msg) 
           //Send email to Y 
           emailHelper.Send(y,anotherMsg) 

          } 
         case 2: 
          { 
           doSomethingelse() 
          } 
          break; 
        } 
        break; 
       } 
      //Inv is waiting 
      case 1: 
       { 
        switch ((int)nextState) 
        { 
         ... 
        } 
       } 
    ... 

내가이 솔루션은 나를 위해 잘 작동 것이라고 생각하지만, 내가 뭔가 better..Any 제안을 사용할 수 있는지가 궁금?

+0

. 첫 번째 다이어그램 [여기] (https://www.codeproject.com/Articles/509234/The-State-Design-Pattern-vs-State-Machine)과 같은 것입니다. – itsme86

+0

하지만 내가 트리거해야하는 동작은 실제 상태가 아닌 상태 전환에 기반을두고 있습니다. –

+0

왜 State Design 패턴이 그 시나리오에서 작동하지 않는지 알 수 없습니다. 'ConcreteState'와 그 책임에 대한 기사의 부분을 읽으십시오. – itsme86

답변

1

(의사 코드)

class StateHandler 
{ 
    int CurrentState; 
    int NextState; 
    Action MyAction; 

    public void Eval(int currentState, int nextState) 
    { 
     if(currentState == this.CurrentState && nextState == this.NextState) 
     { 
      this.MyAction(); 
     } 
    } 
} 

는 목록을 작성하고 모든 알려진 상태 전환으로 채 웁니다. 그런 다음 목록을 반복하고 각 항목에서 Eval()을 호출하십시오.

List<StateHandler> handlers = new List<StateHandler>(); 
handlers.Add(new StateHandler() 
{ 
    currentState = 0, 
    nextState = 1, 
    () => doSomeWork() 
} 
handlers.Add(new StateHandler() 
{ 
    currentState = 3, 
    nextState = 4, 
    () => doSomeOtherWork() 
} 
2

아마도 데이터 구조를 사용하여 상태와 전환을 저장할 수 있습니다. 예를 들어, 상태 머신은

struct State { 
    Dictionary<int, Action> transitions; 
} 

은 물론

var action = states[currentState].transitions[nextState]; 
action(); 
currentState = nextState; 

처럼,이 솔루션은 더 캡슐화 할 수있는 상태 전이가 다음 보이는 공연으로 State이 간단 할 수있는 Dictionary<int, State>, 수,과 수 전환이 존재하는지 여부에 대한 검사를 사용할 수 있지만 이것이 그 요지입니다.

2

성능이 전혀 문제가되지 않으며 원하는 경우 컴팩트 코드라고 생각하면

를 고려하십시오.
switch(string.Format(CultureInfo.InvariantCulture, "{0} {1}", currentState, nextState)) 
{ 
    case "-1 1": 
     //Send email to x 
     emailHelper.Send(x,msg); 
     //Send email to Y 
     emailHelper.Send(y,anotherMsg); 
     break; 
    case "-1 2": 
     doSomethingelse(); 
     break; 
    .... 
} 

또한 C# 7.0을 기다리고 switch statement의 새로운 양식을 사용할 수 있습니다. 이런 식으로 뭔가 : 나는`State` 기본 클래스 또는`IState` 인터페이스와 각각의 실제 상태에 대한 파생 클래스를 선호

struct State 
{ 
    int Current; 
    int Next; 
} 

.... 

State s; 
switch (s) 
{ 
    case State x when (x.Current == -1 && x.Next == 1): 
     .... 
} 
+0

그건 재미있는 생각이에요. –