2013-08-25 3 views
1

Java 클래스에서 Finite State Machine을 구현 중입니다. FSM에 상태를 지정해야하기 때문에 자신의 객체 인 상태와 이벤트가있는 또 다른 예제를 찾을 수 없었습니다 (아마도 그 이유가 있을까요?). 그리고 나는 내 솔루션에 대해 확신하지 못했습니다. (실제 관리자)를 선택하고 FSM을 상태에 할당합니다 (상태 변경을 알리기 위해). 저는 여기에 상태를 할당하는 상태 관리자에 대한 코드, 그리고에 요구한다면, 그것을 밖으로 뱉어 :Java에서 객체 상태가있는 FSM

public class FSM { 

    public void setCurrentState(FSMState newCurrentState) { 
     this.currentState = newCurrentState; 
    } 

    private FSMState currentState; 

    public FSMState getCurrentState() { 
     if (this.currentState == null) 
      System.out.println("No current state"); 
     return this.currentState; 
    } 
} 

여기에 출력 상태로 이벤트를 매핑하는 맵을 사용하는 상태, 그리고의 경우 상태가 관리자에게 통지하지 않았을 있도록

public class FSMState implements EventListener { 

    private FSM managingFSM; 
    private Map<Event,FSMState> transitions; 

    public FSMState(FSM managingFSM) { 
     this.transitions = new HashMap<Event, FSMState>(); 
     this.managingFSM = managingFSM; 
    } 

    public void addEventTransition(Event event, FSMState outputState){ 
     transitions.put(event, outputState); 
     event.registerListener(this); 
    } 

    @Override 
    public void eventOccured(Event e) { 
     FSMState newState = transitions.get(e); 
     this.managingFSM.setCurrentState(newState); 
    } 
} 

방법이 있나요 유사한 솔루션의 종류 : 전환은 FSM 클래스를 통지?

+0

이것은 버그가 발생하기 쉬운 것처럼 보입니다. 언제 FSMStates에 이벤트 전환을 추가합니까? 당신이 지금까지 해왔 던 방식으로 이벤트가 발생하면 등록 된 FSMState (현재 상태에 관계없이)에서 발사하고 현재 상태를 변경합니다. 현재 상태가 해고되기위한 이벤트 만 필요하므로 올바른 전환을 얻을 수 있습니다. – Illidanek

답변

0

구현에 많은 변경이 필요하다고 말하고 싶습니다. 먼저, FSM 자체를 만들기 전에 상태와 전환을 만들려고합니다. FSMManager라는 초기화 및 설정을 관리하는 별도의 클래스를 만들었습니다. 이처럼 보이도록

public class FSMState { 

    private Map<Event,FSMState> transitions; 

    public FSMState() { 
     this.transitions = new HashMap<Event, FSMState>(); 
    } 

    public void addEventTransition(Event event, FSMState outputState){ 
     transitions.put(event, outputState); 
    } 

    public FSMState transition(Event e) { 
     if(transitions.containsKey(e)) { 
      return transitions.get(e); 
     } 
     else { 
      System.out.println("No transition found"); 
      return this; 
     } 
    } 

} 

는 그 다음 FSM 클래스를 변경 :

먼저 변경 FSMState은 단순히이 될 수 있습니다

public class FSMManager { 

    private static final NUM_STATES = 5; 

    public static void main(String[] args) { 

     FSMState[] states = new FSMState[NUM_STATES]; 

     for(FSMState state : states) { 
      state = new FSMState(); 
     } 

     // Then add all the state transitions to all the states 
     states[0].addEventTransition(event1, states[1]); 
     states[1].addEventTransition(event1, states[2]); 
     states[1].addEventTransition(event2, states[4]); 
     // etc, etc 

     //Finally, create the FSM 
     FSM fsm = new FSM(state[0]); 

     //You will also have to register the FSM to listen for all the events 
     event1.registerListener(fsm); 
     event2.registerListener(fsm); 
     ... 


    } 

} 
:

public class FSM implements EventListener { 

    private FSMState currentState; 

    public FSM(FSMState startState) { 
     currentState = startState; 
    } 

    public FSMState getCurrentState() { 
     if (this.currentState == null) 
      System.out.println("No current state"); 
     return this.currentState; 
    } 

    @Override 
    public void eventOccured(Event e) { 
     currentState = currentState.transition(e); 
    } 
} 

마지막으로 모든 것을 초기화하기 위해 관리자를 추가

나는 어디에서 당신이 모든 Events를 얻고 있는지, 그리고 그들이 실제로 전나무인지 어떻게 알지 못한다. 에드.하지만 위의 패턴은 따라야 할 좋은 것입니다. 이렇게하면 이벤트가 시작되면 현재 상태에만 적용됩니다. 동일한 이벤트는 상태 머신에서와 같이 다른 상태에서 다른 전환을 생성합니다. 나는 당신이이 일을 정확히 알고하지 않는 한 당신은 질문이있는 경우/더 문제가 언급 내가 내 대답을 개선하기 위해 노력할 것입니다, 그래서이 솔루션은 도움이

그러나 그것은 완벽하지 않습니다.