怎么用ftp上傳網(wǎng)站seo建站
狀態(tài)機(jī)(State Machine)是一種用于描述系統(tǒng)行為的數(shù)學(xué)模型,廣泛應(yīng)用于計(jì)算機(jī)科學(xué)、工程和自動(dòng)化等領(lǐng)域。它通過(guò)定義系統(tǒng)的狀態(tài)、事件和轉(zhuǎn)移來(lái)模擬系統(tǒng)的動(dòng)態(tài)行為。
基本概念
-
狀態(tài)(State):系統(tǒng)在某一時(shí)刻的特定條件或模式。
-
事件(Event):觸發(fā)狀態(tài)轉(zhuǎn)移的外部輸入或條件變化。
-
轉(zhuǎn)移(Transition):狀態(tài)因事件而發(fā)生的改變。
-
動(dòng)作(Action):在狀態(tài)轉(zhuǎn)移或處于某一狀態(tài)時(shí)執(zhí)行的操作。
簡(jiǎn)單點(diǎn)來(lái)說(shuō)就是某一個(gè)流程當(dāng)前狀態(tài)A->事件1->狀態(tài)B, 或者狀態(tài)A->事件2->C的一個(gè)流程, 實(shí)現(xiàn)起來(lái)也是比較簡(jiǎn)單的
自定義狀態(tài)機(jī)?
基本原理就是根據(jù)狀態(tài)機(jī)的概念簡(jiǎn)單實(shí)現(xiàn)一下, 根據(jù)讀取json文件來(lái)配置整個(gè)流程
狀態(tài)機(jī)配置
@Data
public class StateMachineConfig {/*** 狀態(tài)機(jī)名稱(chēng)(Bean名稱(chēng))*/private String name;/*** 狀態(tài)機(jī)配置*/private List<Transition> transitions;@Datapublic static class Transition {/*** 當(dāng)前狀態(tài)*/private String from;/*** 事件*/private String event;/*** 下一個(gè)狀態(tài)*/private String to;}
}
{"name": "orderProcess","transitions": [{"from": "A","event": "event1","to": "B"},{"from": "A","event": "event2","to": "C"},{"from": "B","event": "event3","to": "C"},{"from": "C","event": "event1","to": "D"}]
}
狀態(tài)機(jī)實(shí)例
這個(gè)類(lèi)主要是狀態(tài)機(jī)的實(shí)例, 也是實(shí)現(xiàn)狀態(tài)機(jī)的核心類(lèi), 主要實(shí)現(xiàn)為T(mén)able類(lèi), 簡(jiǎn)單點(diǎn)說(shuō)就是兩個(gè)key確定一個(gè)value
/*** 狀態(tài)機(jī)實(shí)例類(lèi)** @author zzt* @version 1.0.0*/
@Slf4j
public class SimpleStateMachine {/*** 狀態(tài)轉(zhuǎn)換關(guān)系*/private final Table<String, String, String> table = HashBasedTable.create();/*** 添加狀態(tài)轉(zhuǎn)換關(guān)系* 該方法用于在狀態(tài)機(jī)中添加從當(dāng)前狀態(tài)到新?tīng)顟B(tài)的轉(zhuǎn)換關(guān)系。轉(zhuǎn)換關(guān)系由當(dāng)前狀態(tài)、事件和新?tīng)顟B(tài)組成。** @param fromState 當(dāng)前狀態(tài),表示轉(zhuǎn)換的起始狀態(tài)。* @param event 觸發(fā)狀態(tài)轉(zhuǎn)換的事件。* @param toState 轉(zhuǎn)換后的新?tīng)顟B(tài)。*/public void addTransition(String fromState, String event, String toState) {table.put(fromState, event, toState);}/*** 發(fā)送事件以觸發(fā)狀態(tài)轉(zhuǎn)換* 此方法根據(jù)當(dāng)前狀態(tài)和接收到的事件來(lái)確定是否需要進(jìn)行狀態(tài)轉(zhuǎn)換* 如果當(dāng)前狀態(tài)和事件的組合在轉(zhuǎn)換表中定義了狀態(tài)轉(zhuǎn)換,則執(zhí)行轉(zhuǎn)換* 否則,輸出沒(méi)有可用轉(zhuǎn)換的消息** @param currentState 當(dāng)前狀態(tài)* @param event 觸發(fā)狀態(tài)轉(zhuǎn)換的事件* @return 返回新?tīng)顟B(tài)*/public String sendEvent(String currentState, String event) {//獲取下一個(gè)狀態(tài)String to = table.get(currentState, event);if (StringUtils.isBlank(to)) {log.error("沒(méi)有可用轉(zhuǎn)換, 請(qǐng)檢查配置文件,currentState: [{}], event: [{}]", currentState, event);throw new BusinessException("獲取狀態(tài)異常!");}return to;}
}
?狀態(tài)機(jī)工廠(chǎng)
狀態(tài)機(jī)工廠(chǎng)主要就是用來(lái)生產(chǎn)狀態(tài)機(jī)實(shí)例的, 在實(shí)際項(xiàng)目中可能會(huì)配置多個(gè)流程,因此需要生成多個(gè)狀態(tài)機(jī)實(shí)例, 當(dāng)時(shí)用時(shí)只需要從容器中獲取一個(gè)實(shí)例即可
/*** 狀態(tài)機(jī)實(shí)例工廠(chǎng),負(fù)責(zé)創(chuàng)建狀態(tài)機(jī)并將其注冊(cè)到 Spring IOC 容器中** @author zzt* @version 1.0.0*/
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "state-machine")
public class StateMachineFactory {/*** 是否啟用狀態(tài)機(jī)*/private Boolean enable = false;/*** 狀態(tài)機(jī)配置文件路徑(resources目錄下的包)*/private String path = "";private final ApplicationContext applicationContext;/*** 初始化所有狀態(tài)機(jī)并注冊(cè)到 Spring IOC 容器中*/@Beanpublic void registerStateMachines() {if (enable) {// 獲取所有狀態(tài)機(jī)配置List<StateMachineConfig> stateMachineConfigs = StateMachineJsonUtil.readAllJsonFiles(path);// 獲取狀態(tài)機(jī)配置名稱(chēng)BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory();for (StateMachineConfig config : stateMachineConfigs) {//判斷是否已經(jīng)存在Bean名稱(chēng)if (!registry.containsBeanDefinition(config.getName())) {GenericBeanDefinition beanDefinition = new GenericBeanDefinition();beanDefinition.setBeanClass(SimpleStateMachine.class);beanDefinition.setInstanceSupplier(() -> createStateMachine(config));// 使用狀態(tài)機(jī)名稱(chēng)作為 Bean 名稱(chēng)registry.registerBeanDefinition(config.getName(), beanDefinition);} else {log.error("狀態(tài)機(jī)名稱(chēng):[{}]重復(fù),請(qǐng)檢查配置文件!", config.getName());throw new SpringBootPlusException("狀態(tài)機(jī)名稱(chēng)重復(fù),請(qǐng)檢查配置文件!");}}}}/*** 創(chuàng)建并配置狀態(tài)機(jī)實(shí)例** @param stateMachineConfig 狀態(tài)機(jī)配置* @return 配置好的狀態(tài)機(jī)實(shí)例*/private SimpleStateMachine createStateMachine(StateMachineConfig stateMachineConfig) {// 創(chuàng)建狀態(tài)機(jī)并配置SimpleStateMachine stateMachine = new SimpleStateMachine();// 配置狀態(tài)機(jī)的轉(zhuǎn)換規(guī)則for (StateMachineConfig.Transition transition : stateMachineConfig.getTransitions()) {stateMachine.addTransition(transition.getFrom(), transition.getEvent(), transition.getTo());}return stateMachine;}
}
讀取json文件
/*** 讀取 json 文件** @author zzt* @version 1.0.0*/
@Slf4j
public class StateMachineJsonUtil {/*** 讀取 resources/path 目錄下的所有 .json 文件,并將其解析為 StateMachineConfig 對(duì)象的列表。** @param path json文件路徑* @return 包含所有解析后的 StateMachineConfig 對(duì)象的列表*/public static List<StateMachineConfig> readAllJsonFiles(String path) {ObjectMapper objectMapper = MapperUtils.getInstance();List<StateMachineConfig> stateMachineConfigs = new ArrayList<>();try {ClassPathResource resource = new ClassPathResource(path);File[] files = resource.getFile().listFiles();if (files != null) {// 遍歷每個(gè)資源文件,將其解析為 StateMachineConfig 對(duì)象并添加到列表中for (File file : files) {if (file.exists()) {FileInputStream inputStream = new FileInputStream(file);StateMachineConfig stateMachineConfig = objectMapper.readValue(inputStream, StateMachineConfig.class);stateMachineConfigs.add(stateMachineConfig);}}}} catch (Exception e) {log.error("讀取json文件失敗,[{}]", e.getMessage(), e);throw new SpringBootPlusException("讀取json文件失敗");}return stateMachineConfigs;}
}