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");
  }  
} 

你可能感兴趣的:(java,enum,状态机,售卖机)