`

状态机

 
阅读更多

本例使用状态机演示一个自动售货机的使用场景。

 

状态机接口: 

package statemachine;

/**
 * 状态机接口
 * 
 * @author guweiqiang
 * 2018年7月4日
 */
public interface State {
	
	/**
	 * 定义机器全部动作
	 */
	// 投入硬币
	void insertCoin();
	
	// 退回硬币
	void ejectCoin();
	
	// 转动摇柄
	void turnCrank();
	
	// 喷出糖果
	void dispense();
	
}

 

  

状态机类: 

package statemachine;

/**
 * 状态机类
 * 
 * @author guweiqiang
 * 2018年7月4日
 */
public class Machine {
	
	// 机器包含的所有状态
	private State nonCoinState; // 未投币状态
	private State hasCoinState; // 已投币状态
	private State soldState; // 正在出售状态
	private State soldOutState; // 已售光状态
	
	private State state; // 机器当前状态
	private int count; // 机器中当前的糖果数量
	
	/**
	 * 初始化状态机:引入所有的状态,并初始化糖果数量
	 * @param count
	 */
	public Machine(int count) {
		this.nonCoinState = new NonCoinState(this);
		this.hasCoinState = new HasCoinState(this);
		this.soldState = new SoldState(this);
		this.soldOutState = new SoldOutState(this);
		this.count = count;
		if(this.count>0) {
			this.state = nonCoinState;
		} else {
			this.state = soldOutState;
		}
	}
	
	// 投币
	public void insertCoin() {
		this.state.insertCoin();
	}
	
	// 退回硬币
	public void ejectCoin() {
		this.state.ejectCoin();
	}
	
	// 转动摇柄
	public void turnCrank() {
		this.state.turnCrank();
		this.state.dispense();
	}
	
	// 喷出糖果的内部处理
	public void releaseBall() {
		System.out.println("喷出了1个糖果。");
		if(this.count>0) {
			this.count--;
		}
	}

	// 各个状态的get方法
	public State getNonCoinState() {
		return nonCoinState;
	}

	public State getHasCoinState() {
		return hasCoinState;
	}

	public State getSoldState() {
		return soldState;
	}

	public State getSoldOutState() {
		return soldOutState;
	}

	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

	public int getCount() {
		return count;
	}

}

 

 

 未投币状态类: 

package statemachine;

/**
 * 未投币状态类
 * 
 * @author guweiqiang
 * 2018年7月4日
 */
public class NonCoinState implements State {
	
	private Machine machine;
	
	public NonCoinState(Machine machine) {
		this.machine = machine;
	}

	// 投币
	public void insertCoin() {
		System.out.println("已投入硬币!");
		machine.setState(machine.getHasCoinState());
	}

	// 退回硬币
	public void ejectCoin() {
		System.out.println("没有可退回的硬币!");
	}

	// 转动摇柄
	public void turnCrank() {
		System.out.println("请先投币,再转动摇柄!");
	}

	// 喷出糖果
	public void dispense() {
		System.out.println("尚未投币!");
	}

}

 

 

 已投币状态类: 

package statemachine;

/**
 * 已投币状态类
 * 
 * @author guweiqiang
 * 2018年7月4日
 */
public class HasCoinState implements State {

	private Machine machine;

	public HasCoinState(Machine machine) {
		this.machine = machine;
	}
	
	// 投币
	public void insertCoin() {
		System.out.println("请不要重复投币!");
	}

	// 退回硬币
	public void ejectCoin() {
		System.out.println("已退回硬币!");
		machine.setState(machine.getNonCoinState()); // 重新设置为未投币状态
	}

	// 转动摇柄
	public void turnCrank() {
		System.out.println("转动了摇柄");
		machine.setState(machine.getSoldState()); // 设置机器状态为正在出售
	}

	// 喷出糖果
	public void dispense() {
		System.out.println("请转动摇柄!");
	}

}

 

 

 正在出售状态类: 

package statemachine;

/**
 * 正在出售状态类
 * 
 * @author guweiqiang
 * 2018年7月4日
 */
public class SoldState implements State {
	
	private Machine machine;

	public SoldState(Machine machine) {
		this.machine = machine;
	}
	
	// 投币
	public void insertCoin() {
		System.out.println("请等待,正在出货!");
	}

	// 退回硬币
	public void ejectCoin() {
		System.out.println("正在出货,无法退回硬币!");
	}

	// 转动摇柄
	public void turnCrank() {
		System.out.println("请不要重复转动摇柄!");
	}

	// 喷出糖果
	public void dispense() {
		// 喷出糖果
		machine.releaseBall();
		if(machine.getCount()>0) { // 还有糖果,可以继续出售
			machine.setState(machine.getNonCoinState());
		} else { // 已售光
			machine.setState(machine.getSoldOutState());
		}
	}

}

 

 

 已售光状态类: 

package statemachine;

/**
 * 已售光状态类
 * 
 * @author guweiqiang
 * 2018年7月4日
 */
public class SoldOutState implements State {

	private Machine machine;

	public SoldOutState(Machine machine) {
		this.machine = machine;
	}
	
	// 投币
	public void insertCoin() {
		System.out.println("糖果已售光,请不要投币!");
	}

	// 退回硬币
	public void ejectCoin() {
		System.out.println("没有可退回的硬币!");
	}

	// 转动摇柄
	public void turnCrank() {
		System.out.println("糖果已售光,请不要转动摇柄!");
		machine.setState(machine.getNonCoinState());
	}

	// 喷出糖果
	public void dispense() {
		System.out.println("糖果已售光!");
	}

}

 

  

测试类:

package statemachine;

/**
 * 测试类
 * 
 * @author guweiqiang
 * 2018年7月4日
 */
public class StateMachineTest {

	public static void main(String[] args) {
		Machine machine = new Machine(10);
		for (int i=0; i<12; i++) {
			System.out.println(i+": 当前糖果数量:" + machine.getCount());
			if(i==5) {
				machine.insertCoin();
				machine.ejectCoin();
				continue;
			}
			machine.insertCoin();
			machine.turnCrank();
		}

	}

}

 测试结果:

0: 当前糖果数量:10
已投入硬币!
转动了摇柄
喷出了1个糖果。
1: 当前糖果数量:9
已投入硬币!
转动了摇柄
喷出了1个糖果。
2: 当前糖果数量:8
已投入硬币!
转动了摇柄
喷出了1个糖果。
3: 当前糖果数量:7
已投入硬币!
转动了摇柄
喷出了1个糖果。
4: 当前糖果数量:6
已投入硬币!
转动了摇柄
喷出了1个糖果。
5: 当前糖果数量:5
已投入硬币!
已退回硬币!
6: 当前糖果数量:5
已投入硬币!
转动了摇柄
喷出了1个糖果。
7: 当前糖果数量:4
已投入硬币!
转动了摇柄
喷出了1个糖果。
8: 当前糖果数量:3
已投入硬币!
转动了摇柄
喷出了1个糖果。
9: 当前糖果数量:2
已投入硬币!
转动了摇柄
喷出了1个糖果。
10: 当前糖果数量:1
已投入硬币!
转动了摇柄
喷出了1个糖果。
11: 当前糖果数量:0
糖果已售光,请不要投币!
糖果已售光,请不要转动摇柄!
尚未投币!

 

 

 

 

 

 

分享到:
评论

相关推荐

    fsm_keil_version3_keil有限状态机_fsm打开_8051实现状态机_

    状态机是一种设计模式,常用于控制系统的流程或行为,它定义了一组状态以及在不同条件下的状态转换。在8051单片机上实现状态机,可以有效地组织程序结构,提高代码的可读性和可维护性。Keil是常用的8051单片机开发...

    浅析C# 状态机Stateless

    C# 状态机 Stateless 详解 C# 状态机 Stateless 是一种轻量级的状态机库,能够帮助开发者轻松地创建状态机,实现状态之间的切换。下面是对 C# 状态机 Stateless 的详细介绍。 什么是状态机? 状态机(Finite ...

    StateMachine 状态机机制深入解析

    StateMachine 状态机机制深入解析 StateMachine 状态机机制是指在软件开发中,使用状态机来描述和处理复杂的业务流程。状态机机制可以帮助开发者简化状态机的开发过程,并且可以提高代码的可读性和维护性。在 ...

    状态机实验报告1

    在这个名为“状态机实验报告1”的实验中,我们关注的是状态机的设计和实现,特别是Moore型和Mealy型状态机的区别与应用。 Moore状态机与Mealy状态机是状态机的两种基本类型。Moore状态机的输出只取决于当前状态,而...

    通用有限状态机(FSM: Finite-state machine)自动代码生成器

    通用有限状态机(FSM: Finite-state machine)自动代码生成器. 可以根据配置文件,自动生成状态机代码(C++)。配置文件中只需要定义状态,跃迁条件。然后完善每个状态的动作即可。省去开发过程中手写状态机的麻烦。...

    单片机裸奔之状态机浅谈

    状态机在单片机编程中扮演着至关重要的角色,它是一种设计模式,广泛应用于各种编程语言,包括C语言。状态机的核心概念在于通过定义不同状态、条件、动作和次态来组织程序逻辑,使得程序执行更加高效、可读性强且...

    简单状态机控制步进电机

    在这个项目中,“简单状态机控制步进电机”是利用状态机的设计思想来实现对步进电机的精确控制。状态机是一种用于描述系统行为的模型,它按照预定义的一系列状态进行转换,每个状态对应于特定的操作或行为。 首先,...

    C# 状态机实现

    在编程领域,状态机是一种非常重要的设计模式,它被广泛应用于各种复杂的逻辑控制流程中。在C#中,我们可以利用面向对象的特性来实现状态机,以管理对象在不同状态之间的转换。本篇将深入探讨如何在C#中实现状态机,...

    VHDL——有限状态机

    ### VHDL中的有限状态机设计概述 #### 一、有限状态机(FSM)的重要性与优点 有限状态机(Finite State Machine, FSM)是一种被广泛应用于数字逻辑设计中的模型,尤其在VHDL语言中有着非常重要的地位。在设计复杂的...

    C语言嵌入式状态机架构(含C源码)

    状态机是一种设计模式,常用于处理具有多个状态和转换规则的系统。在嵌入式开发中,它尤其重要,因为这种简洁的模型可以帮助管理复杂的控制流程,提高代码的可读性和可维护性。本资源“C语言嵌入式状态机架构(含C...

    基于vhdl的状态机设计程序

    在数字系统设计中,状态机是一种非常重要的构造模块,它用于控制系统的流程和行为。VHDL(Very High-Speed Integrated Circuit Hardware Description Language)是用于硬件描述的语言,常用于FPGA和ASIC设计。本篇...

    一个有趣的有限状态机的JAVA实现

    在IT领域,有限状态机(Finite State Machine, FSM)是一种重要的设计模式,它在软件工程、计算机科学以及许多其他领域都有广泛的应用。本主题“一个有趣的有限状态机的JAVA实现”将带你探索如何利用Java语言构建一...

    可通信状态机(CSM)是一个基于JKI状态机(JKISM)的LabVIEW应用框架(源码)

    可通信状态机(CSM)是一个基于JKI状态机(JKISM)的LabVIEW应用框架。它遵循 JKISM 的模式,扩展了关键词以描述模块之间的消息通信,包括同步消息、异步消息、状态订阅/取消订阅等概念! 可通信状态机(CSM)是一个...

    C语言高效有限状态机(FSM)详细设计说明书.docx

    《C语言高效有限状态机(FSM)详细设计说明书》 有限状态机(Finite State Machine, FSM)是一种模型理论,它将一个系统的行为描述为一系列可切换的状态,以及这些状态之间的转换。这种模型在IT领域中广泛应用,特别...

    状态机的使用

    状态机在计算机科学中是一种建模工具,常用于描述系统的行为和状态转换。在TCP/IP协议栈中,状态机被广泛应用于理解网络连接的不同阶段,如TCP连接的三次握手和四次挥手过程。TCP(传输控制协议)是互联网协议的一...

    状态机知识 状态机c语言实现

    ### 状态机知识与C语言实现详解 #### 一、状态机基础知识 **状态机**(Finite State Machine, FSM)在软件工程中是一种重要的抽象模型工具,它被广泛应用于各种场景中,例如用户界面的设计、协议栈的开发以及游戏AI...

    VHDL入门状态机序列检测器

    而"钟桦VHDL第一次作业课件.pdf"则可能是钟教授关于VHDL状态机设计的课件,可能涵盖了状态机的基本概念,如何描述状态机,以及如何实现序列检测器的具体步骤。 通过学习这部分内容,学生不仅能掌握VHDL的基础知识,...

    单片机多按键状态机的实现

    单片机多按键状态机的实现是嵌入式系统中常用的一种处理多个按键输入的方法,尤其在资源有限的环境中,如消费电子产品、智能家居设备等。本文将深入探讨如何设计和实现一个这样的系统。 首先,我们需要了解单片机。...

    标准状态机_状态机_

    状态机是一种重要的设计模式,广泛应用于软件工程、计算机科学、电子工程和其他领域。它通过定义一组状态以及在这些状态之间转换的规则来描述系统的行为。理解标准状态机的概念及其应用对于开发高效、可靠且可维护的...

    高效状态机的写法及各自的优缺点

    状态机是一种重要的软件设计模式,它在各种领域如游戏开发、网络协议、硬件设计、软件测试等都有着广泛的应用。本文将深入探讨三种常见的状态机实现方式,并分析它们的优缺点。 1. **枚举型状态机(Enum-based FSM...

Global site tag (gtag.js) - Google Analytics