`
racingbird
  • 浏览: 23689 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

使用Enum的自动贩卖机

 
阅读更多

public enum Input {
	NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100),
	TOOTHPASTER(200), CHIPS(75), SODA(100), SOAP(50),
	ABORT_TRANSACTION{
		public int amount(){
			//Disallow
			throw new RuntimeException("ABORT.acmount()");
		}
	},
	STOP{
		// This must be the last instance
		public int amount(){
			throw new RuntimeException("SHUT_DOWN.amount()");
		}
	};
	int value;
	Input(int value){
		this.value = value;
	}
	Input(){}
//	abstract int amount();
	int amount(){
		return value;	//In cents
	}
	static Random rand = new Random(47);
	public static Input randomSelection(){
		// Don;t include STOP;
		return values()[rand.nextInt(values().length - 1)];
	}
}

 

除了2个特殊的Input实例之外,其他的Input都有相应的价格,因此在接口中

定义了amount()方法。然而, 对那两个特殊Input实例而言,调用amount()方法

并不合适,所以如果调用则抛出异常。

 

 

package enumerated;

import java.util.EnumMap;
import java.util.Iterator;

import Container.Generator;
import static enumerated.Input.*;

enum Category{
	MONEY(NICKEL, DIME, QUARTER),
	TIME_SELECTION( CHIPS, SODA, SOAP),
	QUIT_TRANSACTION(ABORT_TRANSACTION),
	SHUT_DOWN(STOP);
	private Input[] values;
	Category(Input... types){
		values = types;
	}
	private static EnumMap<Input, Category> categories = 
		new EnumMap<Input, Category>(Input.class);
	static{
		for(Category c : Category.class.getEnumConstants()){
			for(Input type : c.values){
				categories.put(type, c);
			}
		}
	}
	public static Category categorize(Input input){
		return categories.get(input);
	}
}

public class VendingMachine {
	private static State state = State.RESTING;
	private static int amount = 0;
	private static Input selection = null;
	enum StateDuration{TRANSIENT}
	enum State{
		RESTING{
			void next(Input input){
				switch(Category.categorize(input)){
					case MONEY:
						amount += input.amount();
						state = ADDING_MONEY;
						break;
					case SHUT_DOWN:
						state = TERMINAL;
					default:
				}
			}
		},
		ADDING_MONEY{
			void next(Input input){
				switch(Category.categorize(input)){
				case MONEY:
					amount += input.amount();
					break;
				case TIME_SELECTION:
					selection = input;
					if(amount < selection.amount())
						System.out.println("Insufficient money for "+selection);
					else
						state = DISPENSING;
					break;
				case QUIT_TRANSACTION:
					state = GIVING_CHANGE;
					break;
				case SHUT_DOWN:
					state = TERMINAL;
					default:
				}
			}
		},
		DISPENSING(StateDuration.TRANSIENT){
			void next(){
				System.out.println("hers is your "+selection);
				amount -= selection.amount();
				state = GIVING_CHANGE;
			}
		},
		GIVING_CHANGE(StateDuration.TRANSIENT){
			void next(){
				if(amount > 0){
					System.out.println("Your change: "+amount);
					amount = 0;
				}
				state = RESTING;
			}
		},
		TERMINAL{
			void output(){
				System.out.println("Halted");
			}
		};
		private boolean isTransient = false;
		State(){}
		State(StateDuration trans){ isTransient = true;}
		void next(Input input){
			throw new RuntimeException("Only call "+"next(Input input) for non-transient states");
		}
		void next(){
			throw new RuntimeException("Only call next() for "+
					"StateDuration.TRANSIENT states");
		}
		void output(){
			System.out.println(amount);
		}
	}
	static void run(Generator<Input> gen){
		while(state!=State.TERMINAL){
			state.next(gen.next());
			while(state.isTransient)
				state.next();
			state.output();
		}
	}
	public static void main(String[] args) {
		Generator<Input> gen = new RandomInputGenerator();
		if(args.length == 1){
			gen = new FileInputGenerator(args[0]);
		}
		run(gen);
	}
}
class RandomInputGenerator implements Generator<Input>{
	public Input next(){
		return Input.randomSelection();
	}
}

class FileInputGenerator implements Generator<Input>{
	private Iterator<String> input;
	public FileInputGenerator(String fileName){
//		input = new TextFile(fileName, ":").iterator();
	}
	public Input next(){
		if(!input.hasNext())
			return null;
		return Enum.valueOf(Input.class, input.next().trim());
	}
}

 

Category enum将不同类型的Input进行分组,因为可以使用categorize()方法为switch语句生成

恰当的Category实例。 使用EnumMap确保了查询时的效率和安全。

 

 

 设计缺陷: 它要求 enum State实例访问的VendingMachine属性必须声明为static,这意味着,

只能有一个VendiingMachine实例(事实上够了,因为每台机,只有一个应该程序)。

分享到:
评论

相关推荐

    Options:有时在某些情况下,您想在OptionSet中使用Enum或希望Enum由Raw的Int类型支持,但同时也具有String标签

    目录介绍特征安装用法设置一个MappedValueRepresentable枚举使用MappedValueCollectionRepresented 使用MappedEnum类型的可编码枚举在ESet中使用OptionSet中的EnumSet 将EnumSet转换为Enum数组使用...

    Java Enum使用Demo源码

    本篇将通过"Java Enum使用Demo源码"深入探讨Java枚举的用法。 首先,枚举在Java中是一个类,可以通过`enum`关键字来声明。例如,我们可以创建一个表示星期的枚举类型: ```java public enum WeekDay { MONDAY, ...

    Java中的Enum的使用与分析

    ### Java中的Enum使用与分析 #### 一、概述 在Java编程语言中,`Enum`是一种特殊的数据类型,用于表示一组固定的常量值。通过枚举(`enum`),开发者可以更加直观地定义一系列预定义的值,并为这些值提供类型安全...

    Laravel开发-enum

    本教程将深入探讨如何在Laravel项目中使用enum类,以及它能为代码质量、可读性和可维护性带来的好处。 1. **什么是PHP枚举(Enums)?** PHP枚举是类型安全的数据结构,允许我们定义一组相关的常量,它们的值在运行时...

    ENUM softphone 安装使用及SDK说明

    - 输入要拨打的电话号码,软件会自动处理ENUM查询并连接至正确的通信路径。 - 实现PC到Phone、PC到PC的通话,以及ENUM查询功能。 4. ENUM SDK ENUM SDK是开发人员使用的工具包,包含了开发ENUM相关的应用程序所需的...

    Enum汇总大全详细讲解

    枚举类型自动实现了`Comparable`接口,这意味着枚举值可以按照它们的自然顺序进行比较。如果需要自定义比较逻辑,可以覆盖`compareTo()`方法。 8. **枚举的迭代**: ```java import java.util.Iterator; import...

    Enum的用法

    4. **使用私有构造函数**:虽然`Enum`禁止公开构造函数,但可以定义私有构造函数并在枚举体内部使用,以便为枚举值提供额外的信息或状态,如描述信息: ```java public enum Color { Red("This is Red"), Green...

    enum类型重定义解决方法

    在编程中,`enum`(枚举)类型是用来定义一组命名的整数常量,它在C++中被广泛使用。然而,在某些情况下,我们可能会遇到`enum`类型的重定义问题,这通常发生在包含不同库或者头文件时,因为这些库可能已经定义了...

    Python中的枚举类型:使用`enum`模块的深入指南

    在Python 3.4中,引入了enum模块,它提供了一个Enum类,使得定义和使用枚举类型变得简单而强大。本文将详细介绍如何在Python中使用enum模块定义枚举,包括枚举的基础概念、定义方法、使用场景以及高级应用。 Python...

    Java枚举类型Enum的用法

    Java枚举类型(Enum)是Java SE 5.0引入的一种新的数据类型,它为开发者提供了更为强大且安全的方式来表示一组常量。...在实际开发中,尤其是在设计模式、状态机或者表示固定集合的场景下,枚举类型是非常有用的工具。

    Java enum的用法详解

    在上面的示例中,我们使用 enum 来定义一个 `Signal` 枚举类型,并在 `TrafficLight` 类中使用 switch 语句来处理不同的信号状态。 用法三:添加新方法 如果我们想要在 enum 中添加新的方法,那么必须在 enum 实例...

    enum 结构分析源码

    在这个“enum 结构分析源码”资源中,我们主要关注的是C语言中的枚举使用和实现。C语言中的enum并不是一种真正的类型,而是对整型变量的一种别名,它提供了更易读的常量名称。 首先,我们来看`enum.c`这个源文件。...

    php-enum, PHP Enum实现灵感来自 SplEnum.zip

    php-enum, PHP Enum实现灵感来自 SplEnum PHP enum 实现来自 SplEnum 为什么?首先,SplEnum 并不集成到PHP中,你必须单独安装它。使用 enum 而不是类常量提供了以下优点:你可以键入提示: function setAction(Ac

    Python库 | enum-0.4.7.tar.gz

    在开发过程中,`enum`库可以用于各种场景,如状态机、错误代码、角色权限等。使用`enum`可以使代码更清晰,减少因硬编码而引入的错误,并提高代码的可测试性。例如,你可以定义一个颜色枚举: ```python from enum ...

    Laravel开发-laravel-enum

    Laravel Enum库是为Laravel应用程序设计的一个扩展,它允许开发者使用枚举类型来替代传统的常量或字符串,从而使得业务逻辑更清晰,减少错误的可能性。下面将详细探讨Laravel Enum的使用、优点以及如何在项目中实现...

    C++中枚举类型(enum)

    如果只给某个枚举元素指定了值,那么下一个元素会自动采用前一个元素的值加1作为自己的值: ```cpp enum box { pencil = 3, pen }; // 此时pen的值为4 ``` #### 枚举与位标志 在实际应用中,枚举类型常用于表示位...

    Python中的枚举类型:使用Enum类的详细指南

    在Python中,枚举类型通过enum模块中的Enum类来实现,这使得代码更加清晰、易于维护,并且可以避免魔术数字和字符串的滥用。本文将详细介绍如何在Python中使用枚举类型,包括枚举的基础概念、创建和使用枚举类的步骤...

    opc enum 32-64安装包

    OPC(OLE for Process Control)是工业自动化领域中一种广泛使用的接口标准,它允许不同的软件应用程序之间进行数据交换。OPC Enum 32-64 安装包是一款专为处理32位和64位操作系统设计的OPC组件,确保在不同系统环境...

    enumdisk1.exe

    用于枚举磁盘设备的 Enumdisk 示例

Global site tag (gtag.js) - Google Analytics