设计模式-状态模式

一、状态模式

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

简单来说,就是用一个“Sate”状态类接口,里面规定了自身不同操作,然后根据自身需要每一个状态都生成一个类。

二、项目背景

糖果机有四种状态,投钱状态,没有投钱状态,转动曲柄状态,售馨状态。

请看原生代码:

package com.oyhp.atom;
//糖果机
public class GumballMachine {
	final static int SOLD_OUT = 0;			//糖果售馨
	final static int NO_QUARTER = 1;		//没有25分钱
	final static int HAS_QUARTER = 2;		//有25分钱
	final static int SOLD = 3;				//售出糖果
	
	int state = SOLD_OUT;
	int count = 0;
	
	public GumballMachine(int count) {
		// TODO Auto-generated constructor stub
		this.count = count;
		if(count > 0){
			state = NO_QUARTER;
		}
	}
	//现在投入25分钱
	public void insertQuarter(){
		if(state == HAS_QUARTER){
			System.out.println("你已经投过25分钱了,无法再继续投入");
		}else if(state == NO_QUARTER){
			state = HAS_QUARTER;
			System.out.println("你已经投入25分钱");
		}else if(state == SOLD_OUT){
			System.out.println("无法投入25分钱,因为糖果已经售完");
		}else if(state == SOLD){
			System.out.println("请等待,正在售出糖果");
		}
	}
	//退回25分钱
	public void ejectQuarter(){
		if(state == HAS_QUARTER){
			System.out.println("25分钱已退回");
			state = NO_QUARTER;
		}else if(state == NO_QUARTER){
			System.out.println("你并没有投入钱");
		}else if(state == SOLD){
			System.out.println("抱歉,糖果正在售出");
		}else if(state == SOLD_OUT){
			System.out.println("你并没有投入25分钱,也无法退回");
		}
	}
	//顾客试着转动售出曲柄
	public void turnCrank(){
		if(state == HAS_QUARTER){
			System.out.println("正在转动曲柄......");
			state = SOLD;
			dispense();
		}else if(state == NO_QUARTER){
			System.out.println("正在转动曲柄,但因为你没有投钱,所以无法售出糖果");
		}else if(state == SOLD){
			System.out.println("抱歉,无法转动两次曲柄");
		}else if(state == SOLD_OUT){
			System.out.println("正在转动曲柄,但没有糖果了,无法售出糖果");
		}
	}
	//发放糖果
	public void dispense(){
		if(state == HAS_QUARTER){
			System.out.println("没有糖果售出");
		}else if(state == NO_QUARTER){
			System.out.println("你需要先支付......");
		}else if(state == SOLD){
			System.out.println("正在售出糖果");
			if(count <= 0){
				System.out.println("抱歉无法售出糖果,因为糖果已售馨");
				state = SOLD_OUT;
			}else{
				System.out.println("糖果已售出");
				count = count - 1;
				state = NO_QUARTER;
			}
		}else if(state == SOLD_OUT){
			System.out.println("没有糖果售出");
		}
	}
	
	@Override
	public String toString() {
		return "GumballMachine [state=" + state + ", count=" + count + "]";
	}
	
	
}
package com.oyhp.atom;

public class Test {
	public static void main(String[] args) {
		//总共5个糖果
		GumballMachine gumballMachine = new GumballMachine(5);
		System.out.println(gumballMachine);
		
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		System.out.println(gumballMachine);
		
		gumballMachine.insertQuarter();
		gumballMachine.ejectQuarter();
		gumballMachine.turnCrank();
		System.out.println(gumballMachine);
		
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.ejectQuarter();
		System.out.println(gumballMachine);
		
		gumballMachine.insertQuarter();
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		System.out.println(gumballMachine);
	}
}

三、状态模式

 1、状态接口 

package com.oyhp.state;
//定义状态接口
public interface State {
	public void insertQuarter();
	public void	ejectQuarter();
	public void turnCrank();
	public void dispense();
}

 2、糖果机

package com.oyhp.state;
//糖果机
public class GumballMachine{
	State soldOutState;
	State noQuarterState;
	State hasQuarterState;
	State soldState;
	State winnerState;
	
	State state = soldOutState;
	int count = 0;
	
	public GumballMachine(int numberGumballs) {
		soldOutState = new SoldOutState(this);
		noQuarterState = new NoQuarterState(this);
		hasQuarterState = new HasQuarterState(this);
		soldState = new SoldState(this);
		winnerState = new WinnerState(this);
		this.count = numberGumballs;
		if(numberGumballs > 0){
			state = noQuarterState;
		}
	}

	public State getWinnerState() {
		return winnerState;
	}

	public int getCount() {
		return count;
	}

	public void insertQuarter() {
		state.insertQuarter();
	}

	public void ejectQuarter() {
		state.ejectQuarter();
	}

	public void turnCrank() {
		state.turnCrank();
	}
	
	public void dispense(){
		state.dispense();
	}

	public void setState(State state){
		this.state = state;
	}
	
	public void releaseBall(){
		System.out.println("正在滚动糖果机售出糖果");
		if(count != 0){
			count = count - 1;
		}
	}

	public State getSoldOutState() {
		return soldOutState;
	}

	public State getNoQuarterState() {
		return noQuarterState;
	}

	public State getHasQuarterState() {
		return hasQuarterState;
	}

	public State getSoldState() {
		return soldState;
	}

	@Override
	public String toString() {
		return "GumballMachine [state=" + state + ", count=" + count + "]";
	}

}

3、五个状态 

五种状态-五个类
package com.oyhp.state;

import java.util.Random;

public class HasQuarterState implements State{
	Random randomWinner = new Random(System.currentTimeMillis());
	GumballMachine gumballState;
	
	public HasQuarterState(GumballMachine gumballMachine) {
		this.gumballState = gumballMachine;
	}

	@Override
	public void insertQuarter() {
		System.out.println("已经投入25分钱,无法再投入");
	}

	@Override
	public void ejectQuarter() {
		System.out.println("25分钱退回");
		//改变状态
		gumballState.setState(gumballState.getNoQuarterState());
	}

	@Override
	public void turnCrank() {
		System.out.println("你正在转动曲柄......");
		int winner = randomWinner.nextInt(10);
		if((winner==0) && (gumballState.getCount() > 1)){
			gumballState.setState(gumballState.getWinnerState());
		}else{
			gumballState.setState(gumballState.getSoldState());
		}
	}

	@Override
	public void dispense() {
		System.out.println("需要先转动曲柄......");
	}
	
	
}
package com.oyhp.state;
//没有25分钱
public class NoQuarterState implements State{
	GumballMachine gumballMachine;
	
	public NoQuarterState(GumballMachine gumballMachine) {
		this.gumballMachine = gumballMachine;
	}
	
	@Override
	public void insertQuarter() {
		System.out.println("你投入了25分钱");
		//改变状态
		gumballMachine.setState(gumballMachine.getHasQuarterState());
	}

	@Override
	public void ejectQuarter() {
		System.out.println("你没有投入25分钱,无法退回");
	}

	@Override
	public void turnCrank() {
		System.out.println("你正在转动曲柄,但没有25分钱");
	}

	@Override
	public void dispense() {
		System.out.println("你需要先支付25分钱");
	}

}
package com.oyhp.state;

public class SoldOutState implements State{
	GumballMachine gumballMachine;
	
	public SoldOutState(GumballMachine gumballMachine) {
		this.gumballMachine = gumballMachine;
	}
	
	@Override
	public void insertQuarter() {
		System.out.println("无法投入糖果,糖果已售馨");
	}

	@Override
	public void ejectQuarter() {
		System.out.println("无法退回,糖果已售馨");
	}

	@Override
	public void turnCrank() {
		System.out.println("转动曲柄,糖果已售馨");
	}

	@Override
	public void dispense() {
		System.out.println("无法售出糖果,糖果已售馨");
	}
	
}
package com.oyhp.state;

public class SoldState implements State{
	GumballMachine gumballMachine;
	
	public SoldState(GumballMachine gumballMachine) {
		this.gumballMachine = gumballMachine;
	}
	
	@Override
	public void insertQuarter() {
		System.out.println("请等待,正在售出糖果......");
	}

	@Override
	public void ejectQuarter() {
		System.out.println("抱歉,正在售出糖果无法退回");
	}

	@Override
	public void turnCrank() {
		System.out.println("正在售出糖果");
	}

	@Override
	public void dispense() {
		//改变状态-售出糖果
		gumballMachine.releaseBall();
		if(gumballMachine.getCount() > 0){
			gumballMachine.setState(gumballMachine.getNoQuarterState());
		}else{
			System.out.println("抱歉,糖果机已经售馨");
			gumballMachine.setState(gumballMachine.getSoldOutState());
		}
	}

}
package com.oyhp.state;

public class WinnerState implements State{
	GumballMachine gumballMachine;
	
	public WinnerState(GumballMachine gumballMachine) {
		this.gumballMachine = gumballMachine;
	}
	
	
	@Override
	public void insertQuarter() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void ejectQuarter() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void turnCrank() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void dispense() {
		System.out.println("恭喜恭喜!你获得两颗糖果!");
		gumballMachine.releaseBall();
		if(gumballMachine.getCount() == 0){
			gumballMachine.setState(gumballMachine.getSoldOutState());
		}else{
			gumballMachine.releaseBall();
			if(gumballMachine.getCount() > 0){
				gumballMachine.setState(gumballMachine.getNoQuarterState());
			}else{
				System.out.println("糖果已经售馨");
				gumballMachine.setState(gumballMachine.getSoldOutState());
			}
		}
	}

}

4、测试

package com.oyhp.state;

public class GumballMachineTestDrive {
	public static void main(String[] args) {
		GumballMachine gumballMachine = new GumballMachine(5);
		
		System.out.println(gumballMachine);
		
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.dispense();
		System.out.println(gumballMachine);
		
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.dispense();
		
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.dispense();
		System.out.println(gumballMachine);
	}
}

 四、状态模式类图

五、总结

1、状态模式允许一个对象基于内部状态而拥有不同的行为。

2、策略模式通过会用行为或算法来配置Context类。

3、状态模式允许Context随着状态的改变而改变行为

4、状态转换可以由State类或Context类控制

5、使用状态模式会导致设计中类的数目大量增加

6、状态类可以被多个Context实例共享

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值