您的位置:首页 > 编程语言 > Java开发

JAVA -- stateless4j StateMachine 使用浅析(一)

2017-12-26 00:00 1221 查看
摘要: 有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在电商场景(订单、物流、售后)、社交(IM消息投递)、分布式集群管理(分布式计算平台任务编排)等场景都有大规模的使用.
参考文章:http://www.timguan.net/2017/06/19/%E7%8A%B6%E6%80%81%E6%9C%BA%E5%BC%95%E6%93%8E%E9%80%89%E5%9E%8B/

业务场景:

我们都玩过超级玛丽这款经典的游戏,里面有一个问题;就是玛丽的状态变化;

/**
* Created by Administrator on 2017/12/26.
*
* 超级玛丽所有存在的状态state
*/
public enum CurrentState {
/**
* 初始化时小形态
*/
SMALL,
/**
* 吃到一个蘑菇时的大形态
*/
BIG,
/**
* 吃到花朵,可攻击形态
*/
ATTACH,
/**
* godead
*/
DEAD

}

/**
* Created by Administrator on 2017/12/26.
*
* 超级玛丽会遇到触发状态改变的trigger
*/
public enum Trigger {

/**
* 蘑菇
*/
MUSHROOM,

/**
* 花朵
*/
FLOWER,

/**
* 妖怪
*/
MONSTER
}

import com.github.oxo42.stateless4j.StateMachineConfig;

/**
* Created by Administrator on 2017/12/26.
*
* state和trigger注册
*/
public class StateConver {

private static StateMachineConfig<CurrentState,Trigger> config = new StateMachineConfig<>();

static {
/**
* 最初为small状态时
*/
config.configure(CurrentState.SMALL)
/**
* 遇到蘑菇触发-->big状态
*/
.permit(Trigger.MUSHROOM,CurrentState.BIG)
/**
* 花朵触发,-->直接变为可攻击状态
*/
.permit(Trigger.FLOWER,CurrentState.ATTACH)
/**
* 妖怪触发,死亡状态
*/
.permit(Trigger.MONSTER,CurrentState.DEAD);

/**
* 最初为big状态
*/
config.configure(CurrentState.BIG)
/**
* 蘑菇触发,状态不变,
* permitReentry方法state变化相同,但具体执行过程有一些区别
*/
.ignore(Trigger.MUSHROOM)
.permit(Trigger.FLOWER,CurrentState.ATTACH)
.permit(Trigger.MONSTER,CurrentState.SMALL);

config.configure(CurrentState.ATTACH)
.ignore(Trigger.MUSHROOM)
.ignore(Trigger.FLOWER)
.permit(Trigger.MONSTER,CurrentState.SMALL);

config.configure(CurrentState.DEAD)
.ignore(Trigger.MUSHROOM)
.ignore(Trigger.FLOWER)
.ignore(Trigger.MONSTER);

}
}

import com.github.oxo42.stateless4j.StateMachine;
import org.junit.Test;

/**
* Created by Administrator on 2017/12/26.
*
* 状态机测试类
*/
public class RunStateMachine {

private static StateMachine<CurrentState,Trigger> stateMachine = new StateMachine<CurrentState, Trigger>(CurrentState.SMALL,StateConver.config);

@Test
public void testStateMachine(){
stateMachine.fire(Trigger.FLOWER);
System.out.println("currentState-->"+stateMachine.getState());
}
}

点击运行:发现竟然报错了... ...

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/JAVA/localRepository-Maven/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/JAVA/localRepository-Maven/org/slf4j/slf4j-jdk14/1.7.25/slf4j-jdk14-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
23:39:32,496 |-INFO in ch.qos.logback.classic.LoggerContext[myAppName] - Could NOT find resource [logback.groovy]
23:39:32,496 |-INFO in ch.qos.logback.classic.LoggerContext[myAppName] - Could NOT find resource [logback-test.xml]
23:39:32,517 |-INFO in ch.qos.logback.classic.LoggerContext[myAppName] - Found resource [logback.xml] at [file:/E:/ideaworkspace/spbmyp/target/classes/logback.xml]
23:39:32,697 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
23:39:32,703 |-INFO in ch.qos.logback.classic.joran.action.ContextNameAction - Setting logger context name as [myAppName]
23:39:32,703 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
23:39:32,706 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [console]
23:39:32,710 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
23:39:32,743 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
23:39:32,746 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [rollingFile]
23:39:32,756 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@1413378318 - Will use zip compression
23:39:32,756 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@1413378318 - Will use the pattern logs/logback_myDemo-%d{yyyy-MM-dd}.%i.log for the active file
23:39:32,760 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@57f23557 - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/logback_myDemo-%d{yyyy-MM-dd}.%i.log.zip'.
23:39:32,760 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@57f23557 - Roll-over at midnight.
23:39:32,774 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@57f23557 - Setting initial period to Fri Oct 20 15:23:10 CST 2017
23:39:32,775 |-WARN in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@57f23557 - SizeAndTimeBasedFNATP is deprecated. Use SizeAndTimeBasedRollingPolicy instead
23:39:32,775 |-WARN in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@57f23557 - For more information see http://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy 23:39:32,776 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
23:39:32,778 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[rollingFile] - Active log file name: logs/logback_myDemo.log
23:39:32,778 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[rollingFile] - File property is set to [logs/logback_myDemo.log]
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.springframework] to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.ibatis] to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.ibatis.common.jdbc.SimpleDataSource] to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.ibatis.common.jdbc.ScriptRunner] to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate] to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [java.sql.Connection] to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [java.sql.Statement] to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [java.sql.PreparedStatement] to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.springframework.amqp] to WARN
23:39:32,779 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
23:39:32,779 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [console] to Logger[ROOT]
23:39:32,780 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [rollingFile] to Logger[ROOT]
23:39:32,780 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
23:39:32,780 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@3d0f8e03 - Registering current configuration as safe fallback point

SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
2017-12-26 23:39:32.786 myAppName [main] INFO  com.github.oxo42.stateless4j.StateMachine - Firing FLOWER

Process finished with exit code 0

其实就是包冲突了,上面的两个包都依赖了SLF4J的包,导入那两个包后SLF4J的包被导入了2次,导致冲入,解决一下:

<!--状态机-->
<dependency>
<groupId>com.github.oxo42</groupId>
<artifactId>stateless4j</artifactId>
<version>2.5.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</exclusion>
</exclusions>
</dependency>

其中:
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</exclusion>
</exclusions>
的意思就是在stateless4j的导包时不导入slf4j的包,这样就不会冲突了;

再次运行测试类:

2017-12-26 23:51:37.386 myAppName [main] INFO  com.github.oxo42.stateless4j.StateMachine - Firing FLOWER
currentState-->ATTACH

成功!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  状态机 stateless4j