• JAVA设计模式学习笔记-状态模式


    一个糖果机项目

    智能糖果机,用Java软件控制糖果机:
    待机
    投入一元硬币
    转动把手
    滑落一颗糖果
    待机(根据机器内糖果库存情况,是否提示售罄)

    项目新需求的困惑
    加入游戏元素:有10%的概率可以拿到2粒糖果

    package com.java.test.statemode;
    
    public class CandyMachine {
    
    	final static int SoldOutState = 0;
    	final static int OnReadyState = 1;
    	final static int HasCoin = 2;
    	final static int SoldState = 3;
    
    	private int state = SoldOutState;
    	private int count = 0;
    
    	public CandyMachine(int count) {
    		this.count = count;
    		if (count > 0) {
    			state = OnReadyState;
    		}
    	}
    
    	public void insertCoin() {
    		switch (state) {
    		case SoldOutState:
    			System.out.println("you can't insert coin,the machine sold out!");
    			break;
    		case OnReadyState:
    			state = HasCoin;
    			System.out
    					.println("you have inserted a coin,next,please turn crank!");
    			break;
    		case HasCoin:
    			System.out.println("you can't insert another coin!");
    
    			break;
    		case SoldState:
    			System.out.println("please wait!we are giving you a candy!");
    
    			break;
    		}
    
    	}
    
    	public void returnCoin() {
    		switch (state) {
    		case SoldOutState:
    			System.out
    					.println("you can't return,you haven't inserted a coin yet!");
    			break;
    		case OnReadyState:
    			System.out.println("you haven't inserted a coin yet!");
    			break;
    		case HasCoin:
    
    			System.out.println("coin return!");
    			state = OnReadyState;
    
    			break;
    		case SoldState:
    			System.out.println("sorry,you already have turned the crank!");
    
    			break;
    		}
    
    	}
    
    	public void turnCrank() {
    		switch (state) {
    		case SoldOutState:
    			System.out.println("you turned,but there are no candies!");
    			break;
    		case OnReadyState:
    			System.out.println("you turned,but you haven't inserted a coin!");
    			break;
    		case HasCoin:
    			System.out.println("crank turn...!");
    			state = SoldState;
    			dispense();
    			break;
    		case SoldState:
    			System.out
    					.println("we are giving you a candy,turning another get nothing,!");
    			break;
    		}
    
    	}
    
    	private void dispense() {
    		count = count - 1;
    		System.out.println("a candy rolling out!");
    		if (count > 0) {
    			state = OnReadyState;
    		} else {
    			System.out.println("Oo,out of candies");
    			state = SoldOutState;
    		}
    
    	}
    
    	public void printstate() {
    
    		switch (state) {
    		case SoldOutState:
    			System.out.println("***SoldOutState***");
    			break;
    		case OnReadyState:
    			System.out.println("***OnReadyState***");
    			break;
    		case HasCoin:
    
    			System.out.println("***HasCoin***");
    
    			break;
    		case SoldState:
    			System.out.println("***SoldState***");
    			break;
    		}
    
    	}
    }
    

    测试类

    package com.java.test.statemode;
    
    public class MainTest {
    	public static void main(String[] args) {
    		CandyMachine mCandyMachine=new CandyMachine(1);
    		
    		mCandyMachine.printstate();
    		
    		mCandyMachine.insertCoin();
    		mCandyMachine.printstate();
    		
    		mCandyMachine.turnCrank();
    		
    		mCandyMachine.printstate();
    		
    		mCandyMachine.insertCoin();
    		mCandyMachine.printstate();
    		
    		mCandyMachine.turnCrank();
    		
    		mCandyMachine.printstate();
    	}
    }
    

    状态模式方案
    状态模式:能根据内部状态的变化,改变对象的行为,看起来好像修改了类

    package com.java.test.statemode.state;
    
    public interface State {
    	public void insertCoin();
    	public void returnCoin();
    	public void turnCrank();
    	public void dispense();
    	public void printstate();
    }
    
    package com.java.test.statemode.state;
    
    public class OnReadyState implements State {
    	private CandyMachine mCandyMachine;
    	public OnReadyState(CandyMachine mCandyMachine)
    	{
    		this.mCandyMachine=mCandyMachine;
    	}
    
    	@Override
    	public void insertCoin() {
    		// TODO Auto-generated method stub
    		System.out
    		.println("you have inserted a coin,next,please turn crank!");
    		mCandyMachine.setState(mCandyMachine.mHasCoin);
    	}
    
    	@Override
    	public void returnCoin() {
    		// TODO Auto-generated method stub
    		System.out.println("you haven't inserted a coin yet!");
    		
    	}
    
    	@Override
    	public void turnCrank() {
    		// TODO Auto-generated method stub
    		System.out.println("you turned,but you haven't inserted a coin!");
    		
    	}
    
    	@Override
    	public void dispense() {
    		// TODO Auto-generated method stub
    
    	}
    
    	@Override
    	public void printstate() {
    		// TODO Auto-generated method stub
    		System.out.println("***OnReadyState***");
    		
    	}
    
    }
    
    package com.java.test.statemode.state;
    
    public class SoldOutState implements State {
    
    	private CandyMachine mCandyMachine;
    	public SoldOutState(CandyMachine mCandyMachine)
    	{
    		this.mCandyMachine=mCandyMachine;
    	}
    
    	@Override
    	public void insertCoin() {
    		// TODO Auto-generated method stub
    		System.out.println("you can't insert coin,the machine sold out!");
    		
    	}
    
    	@Override
    	public void returnCoin() {
    		// TODO Auto-generated method stub
    		System.out
    		.println("you can't return,you haven't inserted a coin yet!");
    
    	}
    
    	@Override
    	public void turnCrank() {
    		// TODO Auto-generated method stub
    		System.out.println("you turned,but there are no candies!");
    		
    	}
    
    	@Override
    	public void dispense() {
    		// TODO Auto-generated method stub
    
    	}
    
    	@Override
    	public void printstate() {
    		// TODO Auto-generated method stub
    		System.out.println("***SoldOutState***");
    	
    	}
    
    }
    
    package com.java.test.statemode.state;
    
    public class SoldState implements State {
    	private CandyMachine mCandyMachine;
    	public SoldState(CandyMachine mCandyMachine)
    	{
    		this.mCandyMachine=mCandyMachine;
    	}
    
    	@Override
    	public void insertCoin() {
    		// TODO Auto-generated method stub
    		System.out.println("please wait!we are giving you a candy!");
    
    	}
    
    	@Override
    	public void returnCoin() {
    		// TODO Auto-generated method stub
    		System.out.println("you haven't inserted a coin yet!");
    		
    	}
    
    	@Override
    	public void turnCrank() {
    		// TODO Auto-generated method stub
    		System.out
    		.println("we are giving you a candy,turning another get nothing,!");
    
    	}
    
    	@Override
    	public void dispense() {
    		// TODO Auto-generated method stub
    		
    		mCandyMachine.releaseCandy();
    		if (mCandyMachine.getCount() > 0) {
    			mCandyMachine.setState(mCandyMachine.mOnReadyState);
    		} else {
    			System.out.println("Oo,out of candies");
    			mCandyMachine.setState(mCandyMachine.mSoldOutState);
    		}
    
    	
    	
    	}
    
    	@Override
    	public void printstate() {
    		// TODO Auto-generated method stub
    		System.out.println("***SoldState***");
    		
    	}
    
    }
    
    
    package com.java.test.statemode.state;
    
    public class WinnerState implements State {
    
    	private CandyMachine mCandyMachine;
    
    	public WinnerState(CandyMachine mCandyMachine) {
    		this.mCandyMachine = mCandyMachine;
    	}
    
    	@Override
    	public void insertCoin() {
    		// TODO Auto-generated method stub
    		System.out.println("please wait!we are giving you a candy!");
    
    	}
    
    	@Override
    	public void returnCoin() {
    		// TODO Auto-generated method stub
    		System.out.println("you haven't inserted a coin yet!");
    
    	}
    
    	@Override
    	public void turnCrank() {
    		// TODO Auto-generated method stub
    		System.out
    				.println("we are giving you a candy,turning another get nothing,!");
    
    	}
    
    	@Override
    	public void dispense() {
    		// TODO Auto-generated method stub
    
    		
    		mCandyMachine.releaseCandy();
    		if (mCandyMachine.getCount() == 0) {
    			mCandyMachine.setState(mCandyMachine.mSoldOutState);
    		} else {
    			System.out.println("you are a winner!you get another candy!");
    			mCandyMachine.releaseCandy();
    			if (mCandyMachine.getCount() > 0) {
    				mCandyMachine.setState(mCandyMachine.mOnReadyState);
    			} else {
    				System.out.println("Oo,out of candies");
    				mCandyMachine.setState(mCandyMachine.mSoldOutState);
    			}
    		}
    
    	}
    
    	@Override
    	public void printstate() {
    		// TODO Auto-generated method stub
    		System.out.println("***WinnerState***");
    
    	}
    
    }
    
    
    package com.java.test.statemode.state;
    
    import java.util.Random;
    
    public class HasCoin implements State {
    	private CandyMachine mCandyMachine;
    
    	public HasCoin(CandyMachine mCandyMachine) {
    		this.mCandyMachine = mCandyMachine;
    	}
    
    	@Override
    	public void insertCoin() {
    		// TODO Auto-generated method stub
    		System.out.println("you can't insert another coin!");
    
    	}
    
    	@Override
    	public void returnCoin() {
    		// TODO Auto-generated method stub
    		System.out.println("coin return!");
    		mCandyMachine.setState(mCandyMachine.mOnReadyState);
    	}
    
    	@Override
    	public void turnCrank() {
    		// TODO Auto-generated method stub
    		System.out.println("crank turn...!");
    		Random ranwinner=new Random();
    		int winner=ranwinner.nextInt(10);
    		if(winner==0)
    		{
    			mCandyMachine.setState(mCandyMachine.mWinnerState);
    
    		}else
    		{
    			mCandyMachine.setState(mCandyMachine.mSoldState);
    
    		}
    		
    	}
    
    	@Override
    	public void dispense() {
    	}
    
    	@Override
    	public void printstate() {
    		// TODO Auto-generated method stub
    		System.out.println("***HasCoin***");
    
    	}
    
    }
    
    

    现在变得非常简洁

    package com.java.test.statemode.state;
    
    public class CandyMachine {
    
    	State mSoldOutState;
    	State mOnReadyState;
    	State mHasCoin;
    	State mSoldState;
    	State mWinnerState;
    	private State state;
    	private int count = 0;
    
    	public CandyMachine(int count) {
    		this.count = count;
    		mSoldOutState = new SoldOutState(this);
    		mOnReadyState = new OnReadyState(this);
    		mHasCoin = new HasCoin(this);
    		mSoldState = new SoldState(this);
    		mWinnerState = new WinnerState(this);
    		if (count > 0) {
    			state = mOnReadyState;
    		} else {
    			state = mSoldOutState;
    		}
    	}
    
    	public void setState(State state) {
    		this.state = state;
    	}
    
    	public void insertCoin() {
    		state.insertCoin();
    	}
    
    	public void returnCoin() {
    		state.returnCoin();
    	}
    
    	public void turnCrank() {
    		state.turnCrank();
    		state.dispense();
    	}
    
    	void releaseCandy() {
    
    		// TODO Auto-generated method stub
    		if (count > 0) {
    			count = count - 1;
    			System.out.println("a candy rolling out!");
    		}
    
    	}
    
    	public int getCount() {
    		return count;
    	}
    
    	public void printstate() {
    		state.printstate();
    	}
    }
    
    

    测试类

    package com.java.test.statemode.state;
    
    public class MainTest {
    	public static void main(String[] args) {
    		CandyMachine mCandyMachine = new CandyMachine(6);
    
    		mCandyMachine.printstate();
    
    		mCandyMachine.insertCoin();
    		mCandyMachine.printstate();
    
    		mCandyMachine.turnCrank();
    
    		mCandyMachine.printstate();
    
    		mCandyMachine.insertCoin();
    		mCandyMachine.printstate();
    
    		mCandyMachine.turnCrank();
    
    		mCandyMachine.printstate();
    	}
    }
    
  • 相关阅读:
    定时任务框架APScheduler学习详解
    Python list 和 str 互转
    python多个变量赋值
    python数据类型转换
    jquery datetimepicker 配置参数
    c#判断是否为合法的email地址
    SQL的四种连接-左外连接、右外连接、内连接、全连接
    SQL表连接查询(inner join、full join、left join、right join)
    简单的日期转换
    递归
  • 原文地址:https://www.cnblogs.com/kristse/p/state.html
Copyright © 2020-2023  润新知