enum 实现售卖机

来源:互联网 发布:淘宝花卉店铺 编辑:程序博客网 时间:2024/04/27 20:52

首先

推荐一下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.javapackage 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");  }  } 
2 1
原创粉丝点击