enum 实现售卖机

首先

推荐一下Google的代码风格

https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s4.8.4.3-switch-default

enum售卖机

1.定义售卖机接受的输入命令:

package com.enumTest.enumStateMac;

import java.util.Arrays;
import java.util.Random;

public enum Input {

    NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100), TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50),

    ABORT_TRANSACTION {
        public int amout() {
            throw new RuntimeException("ABORT.amout()");
        }
    },

    STOP {
        // last instance
        public int amout() {
            throw new RuntimeException("SHUT.amout()");
        }

    };

    // 商品价格
    int value;

    Input(int value) {
        this.value = value;
    }

    Input() {
    }

    int amount() {
        return value;
    }

    static Random rand = new Random(47);

    public static Input randomSelection() {
        // Dont include STOP:
        return values()[rand.nextInt(values().length - 1)];
    }

    public static void main(String[] args) {
    }
}

2.售卖机类

package com.enumTest.enumStateMac;

import static net.mindview.util.Print.*;

import java.util.EnumMap;
import java.util.Iterator;
import java.util.logging.Logger;

import net.mindview.util.TextFile;

import com.java.array.generator.Generator;

enum Category {
    // 定义 Category enum实例
    MONEY(Input.NICKEL, Input.DIME, Input.QUARTER, Input.DOLLAR),

    ITEM_SELECTION(Input.TOOTHPASTE, Input.CHIPS, Input.SODA, Input.SOAP),

    QUIT_TRANSACTION(Input.ABORT_TRANSACTION),

    SHUT_DOWN(Input.STOP);

    // 初始化 Input 实例
    private Input[] values;

    Category(Input... types) {
        values = types;
    }

    private static EnumMap<Input, Category> categories = new EnumMap<Input, Category>(Input.class);

    // 填充categories <输入内容 ,根据输入得到的相应菜单>
    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 {

    // 默认机器 state 为 休息状态
    private static State state = State.RESTING;

    // 默认机器 amount =0 投币金额
    private static int amount = 0;

    private static Input selection = null;

    enum StateDuration {
        TRANSIENT
    } // Tagging enum

    // 机器的状态 枚举实例如下:
    // 待机状态 投币状态 出货状态 找零状态 中断操作状态
    enum State {
        // 按照输入内容 进行不同反应

        // 待机状态 将执行:
        RESTING {
            void next(Input input) {
                try {
                    System.out.println("now State: " + state + " RESTING : input: " + input);
                    Thread.sleep(10000l);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                switch (Category.categorize(input)) {
                // 如果输入是金额 1.投币金额设置 2.机器状态设置为 投币
                case MONEY:
                    amount += input.amount();
                    state = ADDING_MONEY;
                    break;// break to where
                // 如果是 关机
                case SHUT_DOWN:
                    state = TERMINAL;
                    // why ???
                default:
                }
            }
        },

        // 如果机器是投币状态 将执行:
        ADDING_MONEY {
            void next(Input input) {
                try {
                    System.out.println("now State: " + state + " ADDING_MONEY : input: " + input);
                    Thread.sleep(5000l);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                switch (Category.categorize(input)) {
                // 继续投币 操作
                case MONEY:
                    amount += input.amount();
                    break;
                // 选择物品 操作
                case ITEM_SELECTION:
                    selection = input;
                    // 金额不足
                    if (amount < selection.amount())
                        print("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() {
                try {
                    System.out.println("now State: " + state + " DISPENSING : input: ");
                    Thread.sleep(5000l);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // 出货,扣费,置为找零状态
                print("here is your " + selection);
                amount -= selection.amount();
                state = GIVING_CHANGE;
            }
        },
        GIVING_CHANGE(StateDuration.TRANSIENT) {

            void next() {
                try {
                    System.out.println("now State: " + state + " GIVING_CHANGE : input: ");
                    Thread.sleep(5000l);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // 找零 置为待机
                if (amount > 0) {
                    print("Your change: " + amount);
                    amount = 0;
                }
                state = RESTING;
            }
        },
        TERMINAL {
            void output() {
                print("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() {
            print("over amount : " + amount);
        }
    }

    // 售货机 静态方法
    static void run(Generator<Input> gen) {
        while (state != State.TERMINAL) {
            Input inputTemp = gen.next();
            if (null == inputTemp/* 限制性 返回Input 中的一个操作 */) {
                return;
            }
            state.next(inputTemp/* 限制性 返回Input 中的一个操作 */);// 返回输入的Input操作的
                                                          // 相应
            // 如果上一步操作是 待机状态 投币状态 也就是说会有=下一步操作的 操作(会调用 next(para),transient
            // 置为true)。
            while (state.isTransient)
                // state.isTransient 代表有下一步 操作
                state.next();
            state.output();
        }
    }

    public static void main(String[] args) {
        // 获得一个 Input
        Generator<Input> gen = new RandomInputGenerator();
        if (args.length == 1)
            // 输入操作命令 完成命令 初始化
            gen = new FileInputGenerator(args[0]);
        run(gen);
    }
}

// For a basic sanity check:
class RandomInputGenerator implements Generator<Input> {
    public Input next() {
        return Input.randomSelection();
    }
}

// Create Inputs from a file of ‘;’-separated strings:
class FileInputGenerator implements Generator<Input> {
    private Iterator<String> input;

    public FileInputGenerator(String fileName) {
        input = new TextFile(fileName, ";").iterator();
    }

    // 限制性 返回Input 中的一个操作
    public Input next() {
        if (!input.hasNext())
            return null;
        String inputNext = input.next().trim();
        if (inputNext == null || "".equals(inputNext)) {
            System.out.println("指令不合法");
            return Input.ABORT_TRANSACTION;
        }
        Input inputGenerated = Enum.valueOf(Input.class, inputNext);
        System.out.println(inputGenerated);
        return inputGenerated;
    }
}

3.其他的帮助类以及相关接口:

package com.java.array.generator;

public interface Generator<T> {
    T next();
}
//: net/mindview/util/TextFile.java
package net.mindview.util;
import java.io.*;
import java.util.*;

public class TextFile extends ArrayList<String> {
  // Read a file as a single string:
  public static String read(String fileName) {
    StringBuilder sb = new StringBuilder();
    try {
      BufferedReader in= new BufferedReader(new FileReader(
        new File(fileName).getAbsoluteFile()));
      try {
        String s;
        while((s = in.readLine()) != null) {
          sb.append(s);
          sb.append("\n");
        }
      } finally {
        in.close();
      }
    } catch(IOException e) {
      throw new RuntimeException(e);
    }
    return sb.toString();
  }
  // Read a file, split by any regular expression:
  public TextFile(String fileName, String splitter) {
    super(Arrays.asList(read(fileName).split(splitter)));
    // Regular expression split() often leaves an empty
    // String at the first position:
    if(get(0).equals("")) remove(0);
  }
  // Normally read by lines:
  public TextFile(String fileName) {
    this(fileName, "\n");
  }
}
时间: 2024-08-08 18:17:04

enum 实现售卖机的相关文章

Android 开发 之 Enum (枚举) —— @IntDef的使用

官方文档说明,安卓开发应避免使用Enum(枚举类),因为相比于静态常量Enum会花费两倍以上的内存.参 http://developer.android.com/training/articles/memory.html#Overhead 那么如果需要使用Enum应该怎么做呢? https://noobcoderblog.wordpress.com/2015/04/12/java-enum-and-android-intdefstringdef-annotation/ public class

java技术系列(一) Enum

Enum的本质是类,继承自Enum类. enum直接使用==进行比较就可以. 类型的静态values方法,返回左右的枚举实例. ordinal方法返回enum声明中枚举常亮的位置. 适用场景:在实际编程中,存在稳定的有限数据集,如周一到周日,四季名称,男女性别等.适用于枚举. 可以在switch中使用. 1 package testjava; 2 3 import com.alibaba.fastjson.JSON; 4 5 /** 6 * Create with test01 7 * Auth

Rhythmk 一步一步学 JAVA (20) JAVA enum常用方法

JAVA 枚举定义常用方法: 1.static Enum valueOf(Class enum,String name) 返回指定name的枚举类型 2.Static Enum values[] 返回枚举常量集合 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

enum类型

enum  标识符  {枚举符表} 枚举符表中的标识符声明为 int 类型的常量,他们可以用在常量可以出现的任何地方. 如果其中不包括带有 = 的枚举符,则常量值从0开始,且枚举常量从左到右依次递增1. 如果其中包括带有= 的枚举符,则该枚举符的值由该表达式指定,其后的标识符的值从该值开始依次递增 同一作用域中的哥枚举符必须互不相同,也不能与普通变量的命相同,但其值可以相同.

Java中的Enum的使用与分析

示例: public enum EnumTest { FRANK("The given name of me"), LIU("The family name of me"); private String context; private String getContext(){ return this.context; } private EnumTest(String context){ this.context = context; } public stat

ENUM 类型

ENUM 是一种枚举类型,枚举就是一一列举,在创建表的时候将所有的情况都列举出来,那么取值的时候只能是这几种情况的一种,不能是别的.每个枚举值均有一个索引值,索引值从1开始,如果是空字符串则索引值为0,如果是NULL则索引值为NULL,例子如下:

hibernate enum映射详解

hibernate enum映射详解 在这里介绍注解的形式,如果想要了解XML配置的方式,可以自行查找相关资料. 例如以下Entity @Entity @Table(name = "t_user") public class User implements Serializable { /** * */ private static final long serialVersionUID = -9042615274714038279L; @Id @GeneratedValue(stra

枚举Enum 的常用方法

一.枚举介绍 通常定义常量方法和枚举定义常量方法区别 public class State { public static final int ON = 1; public static final Int OFF= 0; } 第一.它不是类型安全的. 你必须确保是int,其次,你还要确保它的范围是0和1. 第二.不够直观. 很多时候你打印出来的时候,你只看到 1 和0 ,但其没有看到代码的人并不知道你的企图. 抛弃你所有旧的public static final常量 枚举是一种规范它规范了参数

enum 与 enum class

c++11中引入了新的枚举类型---->强制枚举类型 // unscoped enum: enum [identifier] [: type] {enum-list};  // scoped enum: enum [class|struct] [identifier] [: type] {enum-list}; 参数说明: identifier:指定给与枚举的类型名称. type:枚举器的基础类型(默认int),所有枚举器都具有相同的基础类型,可能是任何整型. enum-list:枚举中以逗号分