Skip to content

Latest commit

 

History

History
234 lines (192 loc) · 7.75 KB

简单入门.md

File metadata and controls

234 lines (192 loc) · 7.75 KB

简单入门

简单状态机(状态无层次结构,不存在子状态)

Turnstile是一个简单的设备,如果付款完成,您可以访问该设备,并且使用状态机进行建模非常简单。 最简单的形式是只有两个状态,LOCKED和UNLOCKED。 如果您尝试通过它或您付款,可能会发生两个事件,COIN和PUSH。

Turnstile

状态

public enum States {
	LOCKED, UNLOCKED
}

事件

public enum Events {
	COIN, PUSH
}

状态机配置

@Configuration
@EnableStateMachine
static class StateMachineConfig
        extends EnumStateMachineConfigurerAdapter<States, Events> {

    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states)
            throws Exception {
        states
            .withStates()
                .initial(States.LOCKED)   //配置初始状态
                .states(EnumSet.allOf(States.class)); //导入所有状态
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
            throws Exception {
        transitions    		//配置transition
            .withExternal()   
                .source(States.LOCKED)    //当接收到COIN事件
                .target(States.UNLOCKED)  //LOCKED--> UNLOCKED
                .event(Events.COIN)
                .and()
            .withExternal()
                .source(States.UNLOCKED) //当接收到PUSH事件
                .target(States.LOCKED)   //UNLOCKED--> LOCKED
                .event(Events.PUSH);
    	}

}

多层次状态机

Showcase是一个复杂的状态机,显示所有可能的转换拓扑结构,最多可达四级状态嵌套。 Showcase

状态

public enum States {
	S0, S1, S11, S12, S2, S21, S211, S212
}

事件

public enum Events {
	A, B, C, D, E, F, G, H, I
}

状态机配置
状态关系

@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
        throws Exception {
    states
        .withStates()
            .initial(States.S0, fooAction())   //初始化状态,初始化动作
            .state(States.S0)				   //导入状态
            .and()
            .withStates()                      //配置S0的子状态S1  
                .parent(States.S0)         
                .initial(States.S1)
                .state(States.S1)
                .and()
                .withStates()              	   //配置S1的子状态S11、S12
                    .parent(States.S1)       
                    .initial(States.S11)
                    .state(States.S11)
                    .state(States.S12)
                    .and()
            .withStates()                      //配置S0的子状态S2  
                .parent(States.S0)
                .state(States.S2)
                .and()
                .withStates()                  //配置S2的子状态S21、S22
                    .parent(States.S2)
                    .initial(States.S21)
                    .state(States.S21)
                    .and()
                    .withStates()              //配置S21的子状态S211、S212
                        .parent(States.S21)
                        .initial(States.S211)
                        .state(States.S211)
                        .state(States.S212);
	}

状态转移关系

@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
    throws Exception {
	    transitions
	        .withExternal()            
	            .source(States.S1).target(States.S1).event(Events.A)    //A:S1->S1
	            .guard(foo1Guard())                                     //配置guard
	            .and()
	        .withExternal()
	            .source(States.S1).target(States.S11).event(Events.B)   //B:S1->S11
	            .and()
	        .withExternal()
	            .source(States.S21).target(States.S211).event(Events.B) //B:S21->S211
	            .and()
	        .withExternal()
	            .source(States.S1).target(States.S2).event(Events.C)    //C:S1->S2
	            .and()
	        .withExternal()
	            .source(States.S2).target(States.S1).event(Events.C)    //C:S2->S1
	            .and()
	        .withExternal()
	            .source(States.S1).target(States.S0).event(Events.D)    //D:S1->S0
	            .and()
	        .withExternal()
	            .source(States.S211).target(States.S21).event(Events.D) //D:S211->S21
	            .and()
	        .withExternal()
	            .source(States.S0).target(States.S211).event(Events.E)  //E:S0->S211
	            .and()
	        .withExternal()
	            .source(States.S1).target(States.S211).event(Events.F)  //F:S1->S211
	            .and()
	        .withExternal()
	            .source(States.S2).target(States.S11).event(Events.F)   //F:S2->S11
	            .and()
	        .withExternal()
	            .source(States.S11).target(States.S211).event(Events.G) //G:S11->S211
	            .and()
	        .withExternal()
	            .source(States.S211).target(States.S0).event(Events.G)  //G:S211->S0
	            .and()
	        .withInternal()                    							//内部转移,无状态变化 
	            .source(States.S0).event(Events.H)
	            .guard(foo0Guard())
	            .action(fooAction())
	            .and()	
	        .withInternal()                    							//内部转移,无状态变化 
	            .source(States.S2).event(Events.H)
	            .guard(foo1Guard())
	            .action(fooAction())
	            .and()
	        .withInternal()                                             //内部转移,无状态变化    
	            .source(States.S1).event(Events.H)
	            .and()
	        .withExternal()                                             //I:S11->S12 
	            .source(States.S11).target(States.S12).event(Events.I)
	            .and()
	        .withExternal()                                             //I:S211->S212
	            .source(States.S211).target(States.S212).event(Events.I)
	            .and()
	        .withExternal()                                             //I:S12->S212
	            .source(States.S12).target(States.S212).event(Events.I);
	}

action&guard

	@Bean
	public FooGuard foo0Guard() {
	    return new FooGuard(0);
	}
	
	@Bean
	public FooGuard foo1Guard() {
	    return new FooGuard(1);
	}
	
	@Bean
	public FooAction fooAction() {
	    return new FooAction();
	}

	private static class FooAction implements Action<States, Events> {
	
	    @Override
	    public void execute(StateContext<States, Events> context) {
	        Map<Object, Object> variables = context.getExtendedState().getVariables();
	        Integer foo = context.getExtendedState().get("foo", Integer.class);
	        if (foo == null) {
	            log.info("Init foo to 0");
	            variables.put("foo", 0);
	        } else if (foo == 0) {
	            log.info("Switch foo to 1");
	            variables.put("foo", 1);
	        } else if (foo == 1) {
	            log.info("Switch foo to 0");
	            variables.put("foo", 0);
	        }
	    }
	}


	private static class FooGuard implements Guard<States, Events> {
	
	    private final int match;
	
	    public FooGuard(int match) {
	        this.match = match;
	    }
	
	    @Override
	    public boolean evaluate(StateContext<States, Events> context) {
	        Object foo = context.getExtendedState().getVariables().get("foo");
	        return !(foo == null || !foo.equals(match));
	    }
	}