状态模式笔记


状态模式


定义:

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


例子:

1、状态接口,任何状态都实现这个相同的接口,这样一来,状态之间可以互相替换。

public interface State {

	void insertQuarter();
	void ejectQuarter();
	void turnCrank();
	void dispense();
	String getStateName();
	
}

 2、具体状态,每个具体状态都提供了自己对于请求的实现,所以当context(之后的糖果机)改变状态时行为也跟着改变。


-无投币状态

public class NoQuarterState implements State  {

	GumballMachine gumballMachine;
	
	public NoQuarterState(GumballMachine gumballMachine){
		this.gumballMachine = gumballMachine;
	}
	
	@Override
	public void insertQuarter() {
		System.out.println("You inserted a quarter");
		gumballMachine.setState(gumballMachine.getHasQuarterState());
	}

	@Override
	public void ejectQuarter() {
		System.out.println("You havn't inserted a quarter");
	}

	@Override
	public void turnCrank() {
		System.out.println("You turned, but there's no quarter");
	}

	@Override
	public void dispense() {
		System.out.println("You need pay first");
	}

	@Override
	public String getStateName() {
		return "NoQuarterState";
	}

}

- 已投币状态

public class HasQuarterState implements State {

	Random randomWinner = new Random(System.currentTimeMillis());
	GumballMachine gumballMachine;

	public HasQuarterState(GumballMachine gumballMachine) {
		this.gumballMachine = gumballMachine;
	}

	@Override
	public void insertQuarter() {
		/** 此状态不恰当动作 */
		System.out.println("You can't insert another quarter");
	}

	@Override
	public void ejectQuarter() {
		System.out.println("Quarter returned");
		gumballMachine.setState(gumballMachine.getNoQuarterState());
	}

	@Override
	public void turnCrank() {
		System.out.println("You turned ...");
		int winner = randomWinner.nextInt(10);
		if ((winner == 0) && (gumballMachine.getCount() > 1)) {
			gumballMachine.setState(gumballMachine.getWinnerState());
		} else {
			gumballMachine.setState(gumballMachine.getSoldState());
		}
	}

	@Override
	public void dispense() {
		/** 此状态不恰当动作 */
		System.out.println("No gumball dispensed");
	}

	@Override
	public String getStateName() {
		return "HasQuarterState";
	}

}

售出状态

public class SoldState implements State {

	GumballMachine gumballMachine;

	public SoldState(GumballMachine gumballMachine) {
		this.gumballMachine = gumballMachine;
	}

	@Override
	public void insertQuarter() {
		/** 不恰当动作  */
		System.out.println("Please wait, we're already giving you a gumball");
	}

	@Override
	public void ejectQuarter() {
		/** 不恰当动作  */
		System.out.println("Sorry,you already turned the crank");
	}

	@Override
	public void turnCrank() {
		/** 不恰当动作  */
		System.out.println("Turning twice doesn't get you another gumball!");
	}

	@Override
	public void dispense() {
		gumballMachine.releaseBall();
		if(gumballMachine.getCount() > 0){
			gumballMachine.setState(gumballMachine.getNoQuarterState());
		}else{
			System.out.println("Oops, out of gumballs!");
			gumballMachine.setState(gumballMachine.getSoldOutState());
		}

	}

	
	@Override
	public String getStateName() {
		return "SoldState";
	}
}

售空状态

public class SoldOutState implements State {
	
	GumballMachine gumballMachine;

	public SoldOutState(GumballMachine gumballMachine) {
		this.gumballMachine = gumballMachine;
	}

	@Override
	public void insertQuarter() {
		System.out.println("Sorry , no gumball ! You can't inserted a quarter");
	}

	@Override
	public void ejectQuarter() {
		System.out.println("You can't enject.");
	}

	@Override
	public void turnCrank() {
		System.out.println("You turned, but there are no gumballs");
	}

	@Override
	public void dispense() {
		System.out.println("No gumball dispensed");
	}
	
	@Override
	public String getStateName() {
		return "SoldOutState";
	}

}



winner状态(百分之10的机会一下掉2颗 ):


public class WinnerState implements State {
	
	GumballMachine gumballMachine;
	
	public WinnerState(GumballMachine gumballMachine){
		this.gumballMachine = gumballMachine;
	}

	@Override
	public void insertQuarter() {
		System.out.println("You can't insert anthor quarter");
		
	}

	@Override
	public void ejectQuarter() {
		System.out.println("Can't eject, you have turned crank");
	}

	@Override
	public void turnCrank() {
		System.out.println("Needn't turn crank again!");
	}

	@Override
	public void dispense() {
		System.out.println("YOU'RE A WINNER! you get two gumblls for your quarter");
		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("Oops , out of gumballs!");
				gumballMachine.setState(gumballMachine.getSoldOutState());
			}
		}
		
	}

	@Override
	public String getStateName() {
		return "winner state";
	}

}



糖果机,即Context(上下文)

public class GumballMachine {

	State noQuarterState;
	State hasQuarterState;
	State soldState;
	State soldOutState;
	State winnerState;
	
	State state = soldOutState;
	
	int count = 0;
	
	public GumballMachine(int numberGumballs){
		
		 noQuarterState = new NoQuarterState(this);
		 hasQuarterState = new HasQuarterState(this);
		 soldState = new SoldState(this);
		 soldOutState = new SoldOutState(this);
		 winnerState = new WinnerState(this);
		 
		 this.count = numberGumballs;
		 if(numberGumballs > 0){
			 state = noQuarterState;
		 }
	}
	
	public void insertQuarter(){
		state.insertQuarter();
	}
	
	public void ejectQuarter(){
		state.ejectQuarter();
	}
	
	public void turnCrank(){
		state.turnCrank();
		state.dispense();
	}
	
	void setState(State state){
		this.state = state;
	}
	
	void releaseBall(){
		System.out.println("A gumball comes rolling out the slot ...");
		if(count != 0){
			count = count - 1;
		}
	}

	public State getNoQuarterState() {
		return noQuarterState;
	}

	public State getHasQuarterState() {
		return hasQuarterState;
	}

	public State getSoldState() {
		return soldState;
	}

	public State getSoldOutState() {
		return soldOutState;
	}

	public State getWinnerState(){
		return winnerState;
	}
	
	public int getCount(){
		return count;
	}
	
	public String toString(){
		System.out.println(" --- Gumball Machine ---");
		System.out.println("gumball numbers :  " + count);
		System.out.println("machine states : " + state.getStateName());
		return null;
	} 
	
}

测试类:

public class MyGumballMachine {
	
	public static void main(String[] args){
		GumballMachine gumballMachine = new GumballMachine(5);
		
		gumballMachine.toString();
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		
		gumballMachine.toString();
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		gumballMachine.insertQuarter();
		gumballMachine.turnCrank();
		
		gumballMachine.toString();
	}
	
}

结果:

 --- Gumball Machine ---
gumball numbers :  5
machine states : NoQuarterState
You inserted a quarter
You turned ...
A gumball comes rolling out the slot ...
 --- Gumball Machine ---
gumball numbers :  4
machine states : NoQuarterState
You inserted a quarter
You turned ...
A gumball comes rolling out the slot ...
You inserted a quarter
You turned ...
YOU'RE A WINNER! you get two gumblls for your quarter
A gumball comes rolling out the slot ...
A gumball comes rolling out the slot ...
You inserted a quarter
You turned ...
A gumball comes rolling out the slot ...
Oops, out of gumballs!
 --- Gumball Machine ---
gumball numbers :  0
machine states : SoldOutState

结果:


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

- 和程序状态机(PSM)不同,状态模式用类代表状态。

- Context会将行为委托给当前对象。

- 通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了!

- 状态模式和策略模式有相同的类图,但是它们的意图不同。

- 策略模式通常会用行为或算法来配置Context类。

- 状态模式允许Context随着状态的改变而改变行为。

- 状态改变可以由State类或Context类控制。

- 使用状态模式通常会导致设计中类的数目大量增加。

- 状态类可以被多个Context实例共享。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值