enum状态机_demo

Input

package com.enumState;

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
    {
        ;
        @Override
        int amount()
        {
            throw new RuntimeException("ABORT.amount()");
        }
    },
    STOP
    {
        @Override
        int amount()
        {
            throw new RuntimeException("SHUT_DOWN.amount()");
        }
    };

    int value;

    Input()
    {
    }

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

    int amount()
    {
        return value;
    }

    static Random random = new Random(47);

    public static Input randonSelection()
    {
        // Don't include STOP
        return values()[random.nextInt(values().length - 1)];
    }
}

Generator

package com.enumState;

public interface Generator<T>
{
    T next();
}

VendingMachine

package com.enumState;

import static com.enumState.Input.ABORT_TRANSACTION;
import static com.enumState.Input.CHIPS;
import static com.enumState.Input.DIME;
import static com.enumState.Input.DOLLAR;
import static com.enumState.Input.NICKEL;
import static com.enumState.Input.QUARTER;
import static com.enumState.Input.SOAP;
import static com.enumState.Input.SODA;
import static com.enumState.Input.STOP;
import static com.enumState.Input.TOOTHPASTE;

import java.util.EnumMap;

enum Category
{
    MONEY(NICKEL, DIME, QUARTER, DOLLAR),

    ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP),

    /**
     * 退出交易
     */
    QUIT_TRANSACTION(ABORT_TRANSACTION),

    SHUT_DOWN(STOP);

    private Input[] values;

    Category(Input... types)
    {
        this.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);
            }
        }

        System.out.println("categories : "+categories);
    }

    // 获取相应type的值
    public static Category categorize(Input type)
    {
        return categories.get(type);
    }
}

public class VendingMachine
{
    private static State state = State.RESTING;

    private static int amount = 0;

    private static Input selection = null;

    enum StateDuration
    {
        TRANSIENT
    };// Tagging enum

    enum State
    {
        /**
         * 休息
         */
        RESTING
        {
            @Override
            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
        {
            @Override
            void next(Input input)
            {
                switch (Category.categorize(input))
                {
                    case MONEY:
                        amount += input.amount();
                        state = ADDING_MONEY;
                        break;
                    case ITEM_SELECTION:
                        selection = input;
                        if (amount < input.amount())
                            System.out.println("Your money is not enough. ");
                        else
                            state = DISPENSING;
                        break;
                    case QUIT_TRANSACTION:
                        state = GIVING_CHANGE;
                        break;
                    case SHUT_DOWN:
                        state = TERMINAL;
                    default:
                }
            }
        },
        /**
         * 配送
         */
        DISPENSING(StateDuration.TRANSIENT)
        {
            @Override
            void next()
            {
                System.out.println("here is your " + selection);
                amount-=selection.amount();
                state=GIVING_CHANGE;
            }
        },
        /**
         * 进行更改
         */
        GIVING_CHANGE(StateDuration.TRANSIENT)
        {
            @Override
            void next()
            {
                if (amount > 0)
                {
                    System.out.println("Your change : " + amount);
                    amount = 0;
                }
                state = RESTING;
            }
        },
        /**
         * 终点
         */
        TERMINAL
        {
            @Override
            void output()
            {
                System.out.println("Halted");
            }
        };

        private boolean isTransient = false;

        State()
        {
        };

        State(StateDuration trans)
        {
            isTransient = true;
        };

        void next(Input input)
        {
            throw new RuntimeException("input od next find exception");
        }

        void next()
        {
            throw new RuntimeException("next find exception");
        }

        void output()
        {
            System.out.println(amount);
        }
    }

    //
    static void run(Generator<Input> gen)
    {
        while (state != State.TERMINAL)
        {
            Input next = gen.next();
            state.next(next);
            while (state.isTransient)
            {
                state.next();
            }
            state.output();
        }
    }

    // test
    public static void main(String[] args)
    {
        Generator<Input> gen = new RandomGenerator();
        run(gen);
    }

} // 随机生成

class RandomGenerator implements Generator<Input>
{
    @Override
    public Input next()
    {
        return Input.randonSelection();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值