2017-01-23 2 views
0

Ich arbeite an meiner ersten asp.net mvc Webanwendung. Ich habe eine Form, die in 14 verschiedenen Zuständen sein kann und abhängig vom aktuellen Zustand ist oder ist ein Übergang in andere Zustände nicht möglich. Es gibt einen Durchschnitt von 3-5 verschiedenen möglichen nächsten Zuständen für jeden aktuellen Zustand.Zustandsmaschine - eingebetteter Schalter

Was ich jetzt tun muss, ist die Auslösung von Aktionen während eines Zustandsübergangs. Abhängig vom Anfangszustand und den Endzuständen werden einige Aktionen ausgelöst (z. B. werden E-Mails gesendet).

Ich begann diese durch Switch-Anweisungen mit:

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) 
        { 
         ... 
        } 
       } 
    ... 

Ich denke, diese Lösung für mich gut funktionieren würde, aber ich frage mich, ob ich etwas better..Any Vorschläge verwenden könnte?

+0

Ich bevorzuge eine 'State' Basisklasse oder' IState' Schnittstelle und eine abgeleitete Klasse für jeden tatsächlichen Zustand. Etwas wie das erste Diagramm [hier] (https://www.codeproject.com/Articles/509234/The-State-Design-Pattern-vs-State-Machine). – itsme86

+0

Aber die Aktion, die ich auslösen muss, basieren auf Zustandsübergang und nicht auf dem tatsächlichen Zustand –

+0

Ich sehe nicht, warum das State Design-Muster in diesem Szenario nicht funktionieren würde. Lesen Sie den Teil des Artikels über 'ConcreteState' und seine Verantwortlichkeiten. – itsme86

Antwort

1

(Pseudocode)

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

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

eine Liste erstellen und es mit allen bekannten Zustandsübergänge füllen. Dann iteriere einfach die Liste und rufe Eval() für jedes Element auf.

2

Vielleicht könnten Sie eine Datenstruktur verwenden, um die Zustände und Übergänge zu speichern. Zum Beispiel könnte die Zustandsmaschine ein Dictionary<int, State>, wo State könnte so einfach sein wie

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

ein Zustandsübergang durchführen dann wie

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

Natürlich sieht, könnte diese Lösung eingekapselt werden, und könnte prüfen, ob ein Übergang existiert, aber das ist der Kern davon

2

Wenn die Leistung überhaupt kein Problem ist, und das einzige, was Sie interessiert, ist kompakter Code, betrachten

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; 
    .... 
} 

Sie können auch auf C# 7.0 warten und die neue Form switch statement verwenden. So etwas wie das:

struct State 
{ 
    int Current; 
    int Next; 
} 

.... 

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

Das ist eine interessante Idee. –

Verwandte Themen