• 设计模式之状态模式浅析


       
    /**
     * 
     * 状态模式:
     *   允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类
     *   
     * 封装基于状态的行为,并将行为委托到当前状态 
     * 通过把状态封装进一个类,把以后要做的事情局部化了
     * 
     * 策略模式和状态模式有相同的类图,但是彼此的意图不同
     * 
     * State接口定义了一个所有具体状态的共同接口
     * Context是一个类,他可以拥有一些内部状态   糖果机就是Context
     *   
     * 示例
     *   糖果机模型
     *    5个状态:没有5块钱状态、有5块钱状态、赢家模式状态、出售糖果状态  、糖果售罄状态
     *    4个动作:投5块钱、退5块钱、按钮售出按钮、售出糖果
     *    
     * 
     * @author Administrator
     *
     */


    状态接口 封装行为

    package com.undergrowth.state;
    
    /**
     * 
     * 状态模式:
     *   允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类
     *   
     * 封装基于状态的行为,并将行为委托到当前状态 
     * 通过把状态封装进一个类,把以后要做的事情局部化了
     * 
     * 策略模式和状态模式有相同的类图,但是彼此的意图不同
     * 
     * State接口定义了一个所有具体状态的共同接口
     * Context是一个类,他可以拥有一些内部状态   糖果机就是Context
     *   
     * 示例
     *   糖果机模型
     *    5个状态:没有5块钱状态、有5块钱状态、赢家模式状态、出售糖果状态  、糖果售罄状态
     *    4个动作:投5块钱、退5块钱、按钮售出按钮、售出糖果
     *    
     * 
     * @author Administrator
     *
     */
    public interface State {
    	
    	public void insertCoins();
    	public void coinsHopper();
    	public void pressSold();
    	public void soldCandy();
    	
    }
    


    没有5块钱状态
    package com.undergrowth.state;
    
    /**
     * 没有5块钱的状态
     * @author Administrator
     *
     */
    public class NoMoneyState implements State {
    
    	GumballMachine gumballMachine;
    	
    	public NoMoneyState(GumballMachine gumballMachine) {
    		super();
    		this.gumballMachine = gumballMachine;
    	}
    
    	@Override
    	public void insertCoins() {
    		// TODO Auto-generated method stub
    		System.out.println("你投了5块钱");
    		gumballMachine.setState(gumballMachine.getHasMoneyState());
    	}
    
    	@Override
    	public void coinsHopper() {
    		// TODO Auto-generated method stub
    		System.out.println("你没有投钱,甭想退钱");
    	}
    
    	@Override
    	public void pressSold() {
    		// TODO Auto-generated method stub
    		System.out.println("你没有投钱,甭想买糖果");
    	}
    
    	@Override
    	public void soldCandy() {
    		// TODO Auto-generated method stub
    		System.out.println("你没有投钱,甭想买糖果");
    	}
    
    }
    

    有5块钱状态

    package com.undergrowth.state;
    
    import java.util.Random;
    
    public class HasMoneyState implements State {
    
    	GumballMachine gumballMachine;
    	// 记录是够进入玩家模式
    	Random randomWinner = new Random(System.currentTimeMillis());
    
    	public HasMoneyState(GumballMachine gumballMachine) {
    		// TODO Auto-generated constructor stub
    		this.gumballMachine = gumballMachine;
    	}
    
    	@Override
    	public void insertCoins() {
    		// TODO Auto-generated method stub
    		System.out.println("已经投过币了,不要在投币了");
    	}
    
    	@Override
    	public void coinsHopper() {
    		// TODO Auto-generated method stub
    		System.out.println("退币成功");
    		gumballMachine.setState(gumballMachine.getNoMoneyState());
    	}
    
    	@Override
    	public void pressSold() {
    		// TODO Auto-generated method stub
    		System.out.println("你按下售出糖果按钮,即将售出糖果");
    		int winner = randomWinner.nextInt(10);
    		//十分之一机会 进入赢家模式
    		if (winner == 0 && gumballMachine.getCount() > 1) {
    			gumballMachine.setState(gumballMachine.getWinnerState());
    		} else {
    			gumballMachine.setState(gumballMachine.getSoldState());
    		}
    
    	}
    
    	@Override
    	public void soldCandy() {
    		// TODO Auto-generated method stub
    		System.out.println("你没有操作,甭想售出糖果");
    	}
    
    }
    

    售出糖果状态

    package com.undergrowth.state;
    
    public class SoldState implements State {
    
    	GumballMachine gumballMachine;
    	public SoldState(GumballMachine gumballMachine) {
    		// TODO Auto-generated constructor stub
    		this.gumballMachine=gumballMachine;
    	}
    
    	@Override
    	public void insertCoins() {
    		// TODO Auto-generated method stub
    		System.out.println("正在售出糖果,不要投币");
    	}
    
    	@Override
    	public void coinsHopper() {
    		// TODO Auto-generated method stub
    		System.out.println("正在售出糖果,不要退币");
    	}
    
    	@Override
    	public void pressSold() {
    		// TODO Auto-generated method stub
    		System.out.println("正在售出糖果,不要再按下售出按钮了");
    	}
    
    	@Override
    	public void soldCandy() {
    		// TODO Auto-generated method stub
    		gumballMachine.releaseCandy();
    		if(gumballMachine.getCount()>0){
    			gumballMachine.setState(gumballMachine.getNoMoneyState());
    		}else {
    			System.out.println("没有糖果了,进入糖果售罄状态");
    			gumballMachine.setState(gumballMachine.getSoldOutState());
    		}
    	}
    
    }
    


    赢家模式状态

    package com.undergrowth.state;
    
    public class WinnerState implements State {
    
    	GumballMachine gumballMachine;
    	public WinnerState(GumballMachine gumballMachine) {
    		// TODO Auto-generated constructor stub
    		this.gumballMachine=gumballMachine;
    	}
    
    	@Override
    	public void insertCoins() {
    		// TODO Auto-generated method stub
    		System.out.println("正在售出糖果,不要投币");
    	}
    
    	@Override
    	public void coinsHopper() {
    		// TODO Auto-generated method stub
    		System.out.println("正在售出糖果,不要退币");
    	}
    
    	@Override
    	public void pressSold() {
    		// TODO Auto-generated method stub
    		System.out.println("正在售出糖果,不要再按下售出按钮了");
    	}
    
    	@Override
    	public void soldCandy() {
    		// TODO Auto-generated method stub
    		System.out.println("你进入了赢家模式,会获得两个糖果");
    		gumballMachine.releaseCandy();
    		if(gumballMachine.getCount()==0){
    			System.out.println("没有糖果了,进入糖果售罄状态");
    			gumballMachine.setState(gumballMachine.getSoldOutState());
    		}else {
    			gumballMachine.releaseCandy();
    			if(gumballMachine.getCount()>0){
    				gumballMachine.setState(gumballMachine.getNoMoneyState());
    			}else {
    				System.out.println("没有糖果了,进入糖果售罄状态");
    				gumballMachine.setState(gumballMachine.getSoldOutState());
    			}
    		}
    	}
    
    }
    

    糖果售完状态

    package com.undergrowth.state;
    
    public class SoldOutState implements State {
    
    	GumballMachine gumballMachine;
    	public SoldOutState(GumballMachine gumballMachine) {
    		// TODO Auto-generated constructor stub
    		this.gumballMachine=gumballMachine;
    	}
    
    	@Override
    	public void insertCoins() {
    		// TODO Auto-generated method stub
    		System.out.println("没有糖果了,不要投币");
    	}
    
    	@Override
    	public void coinsHopper() {
    		// TODO Auto-generated method stub
    		System.out.println("没有糖果了,不要退币");
    	}
    
    	@Override
    	public void pressSold() {
    		// TODO Auto-generated method stub
    		System.out.println("没有糖果了,不要按下售出按钮");
    	}
    
    	@Override
    	public void soldCandy() {
    		// TODO Auto-generated method stub
    		System.out.println("没有糖果了");
    	}
    
    }
    

    糖果机 拥有一系列的状态  同时拥有当前状态

    package com.undergrowth.state;
    
    /**
     * 糖果机器
     * 
     * @author Administrator
     * 
     */
    public class GumballMachine {
    
    	//状态切换在这5个状态之间
    	State noMoneyState;
    	State hasMoneyState;
    	State soldState;
    	State soldOutState;
    	State winnerState;
    	// 当前状态
    	State state;
    	//糖果剩余数
    	int count;
    
    	public GumballMachine(int numCandy) {
    		noMoneyState = new NoMoneyState(this);
    		hasMoneyState = new HasMoneyState(this);
    		winnerState = new WinnerState(this);
    		soldState = new SoldState(this);
    		soldOutState = new SoldOutState(this);
    		this.count = numCandy;
    		if (numCandy > 0) {
    			state = noMoneyState;
    		}
    	}
    
    	public void insertCoins(){
    		state.insertCoins();
    	}
    	public void coinsHopper(){
    		state.coinsHopper();
    	}
    	public void pressSold(){
    		state.pressSold();
    		state.soldCandy();
    	}
    	
    	void releaseCandy(){
    		if(count!=0){
    			System.out.println("你获得一个糖果");
    			count=count-1;
    		}
    	}
    	
    	
    	public State getNoMoneyState() {
    		return noMoneyState;
    	}
    
    	public State getHasMoneyState() {
    		return hasMoneyState;
    	}
    
    	public State getSoldState() {
    		return soldState;
    	}
    
    	public State getSoldOutState() {
    		return soldOutState;
    	}
    
    	public State getWinnerState() {
    		return winnerState;
    	}
    
    	public State getState() {
    		return state;
    	}
    
    	public int getCount() {
    		return count;
    	}
    
    	public void setState(State state) {
    		this.state = state;
    	}
    
    	@Override
    	public String toString() {
    		return "GumballMachine [state=" + state + ", count=" + count + "]";
    	}
    
    	
    }
    


    测试

    package com.undergrowth.state.test;
    
    import static org.junit.Assert.*;
    
    import org.junit.Test;
    
    import com.undergrowth.state.GumballMachine;
    
    public class GumballMachineTest {
    
    	@Test
    	public void test() {
    		GumballMachine gumball=new GumballMachine(10);
    		System.out.println(gumball);
    		gumball.insertCoins();
    		gumball.pressSold();
    		System.out.println(gumball);
    		gumball.insertCoins();
    		gumball.pressSold();
    		System.out.println(gumball);
    		gumball.coinsHopper();
    		gumball.insertCoins();
    		System.out.println(gumball);
    		gumball.coinsHopper();
    		System.out.println(gumball);
    		gumball.insertCoins();
    		gumball.pressSold();
    		System.out.println(gumball);
    		gumball.insertCoins();
    		gumball.pressSold();
    		gumball.insertCoins();
    		gumball.pressSold();
    		gumball.insertCoins();
    		gumball.pressSold();
    		System.out.println(gumball);
    	}
    
    }
    

    输出结果

    GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=10]
    你投了5块钱
    你按下售出糖果按钮,即将售出糖果
    你获得一个糖果
    GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=9]
    你投了5块钱
    你按下售出糖果按钮,即将售出糖果
    你进入了赢家模式,会获得两个糖果
    你获得一个糖果
    你获得一个糖果
    GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=7]
    你没有投钱,甭想退钱
    你投了5块钱
    GumballMachine [state=com.undergrowth.state.HasMoneyState@95ef17, count=7]
    退币成功
    GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=7]
    你投了5块钱
    你按下售出糖果按钮,即将售出糖果
    你获得一个糖果
    GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=6]
    你投了5块钱
    你按下售出糖果按钮,即将售出糖果
    你获得一个糖果
    你投了5块钱
    你按下售出糖果按钮,即将售出糖果
    你获得一个糖果
    你投了5块钱
    你按下售出糖果按钮,即将售出糖果
    你获得一个糖果
    GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=3]
    



       状态模式:封装基于状态的行为,并将行为委托给当前状态


  • 相关阅读:
    C# 日期帮助类【原创】
    C# 发送邮件
    每日一题力扣453
    每日力扣628
    每日一题力扣41巨坑
    每日一题力扣274
    每日一题力扣442有坑
    每日一题力扣495
    每日一题力扣645
    每日一题力扣697
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275537.html
Copyright © 2020-2023  润新知