`
racingbird
  • 浏览: 23356 次
  • 性别: 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, ...

    Laravel开发-enum

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

    Enum汇总大全详细讲解

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

    Enum的用法

    Enum的用法Enum的用法Enum的用法Enum的用法

    Java中的Enum的使用与分析

    Java中的Enum的使用与分析

    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的使用、优点以及如何在项目中实现...

    opc enum 32-64安装包

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

    enum类型重定义解决方法

    常见的enum类型重定义的解决方法,清晰明了。

    enumdisk1.exe

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

    enum 简单使用例子

    本文将深入探讨`enum`的简单使用方法以及如何结合委托(delegate)进行应用。 首先,我们来看如何声明一个枚举。在C#中,你可以使用`enum`关键字来创建一个新的枚举类型。下面是一个简单的例子: ```csharp public...

    enum类型被intent所携带时各种情况的示例代码

    然而,对于enum(枚举)类型,由于它不是Android系统默认支持的数据传递类型,所以在使用Intent传递enum时需要特别处理。本教程将详细讲解enum类型如何与Intent结合,以及在不同情况下如何实现数据传输。 首先,让...

    java enum 枚举 学习资料

    "Java Enum 枚举学习资料" Java Enum 枚举学习资料是 Java 编程语言中的一种特殊类型,它主要用来实现一组固定的常量。 Enum 枚举类型是 Java 5 中引入的一种新特性,旨在解决传统的 int 枚举常量的缺陷。 1. 枚举...

Global site tag (gtag.js) - Google Analytics