状态模式(State Pattern)

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


类图本质上和策略模式一样

差别就在于策略模式偏重于外部或者是对象本身对行为的改变,而状态模式是在于对象内部随着时间的变化,事件的发生,对象状态发生变化后而导致的行为发生变化

更加简单的说,策略模式偏向于主动改变行为,而状态模式偏向于被动改变行为


改自《Head First》课后:糖果贩卖机


代码实现:

public abstract class State {
	
	public void putMoney() {
		System.out.println("Error state, can't put money");
	}
	
	public void backMoney() {
		System.out.println("Error state, can't back money");
	}
	
	public boolean turnHandle() {
		System.out.println("Error state, turn handle no effect");
		return false;
	}
	
	public void provideSugar() {
		System.out.println("Error state, can't provide sugar");
	}
	
	public void refillSugar() {
		System.out.println("Error state, can't refill sugar");
	}
}

public class NoMoneyState extends State {
	
	private SugarMachine machine;

	public NoMoneyState(SugarMachine sugarMachine) {
		machine = sugarMachine;
	}
	
	@Override
	public void putMoney() {
		System.out.println("Put money");
		machine.setState(machine.getHasMoneyState());
	}
}

public class HasMoneyState extends State {

	private SugarMachine machine;

	public HasMoneyState(SugarMachine sugarMachine) {
		machine = sugarMachine;
	}

	@Override
	public void backMoney() {
		System.out.println("Money back");
		machine.setState(machine.getNoMoneyState());
	}

	@Override
	public boolean turnHandle() {
		int random = new Random(System.currentTimeMillis()).nextInt(10);
		if (random == 0 && machine.getCount() > 1) {
			machine.setState(machine.getWinnerState());
			return true;
		} else {
			machine.setState(machine.getSoldState());
			return true;
		}
	}
}

public class SoldState extends State {
	
	private SugarMachine machine;

	public SoldState(SugarMachine sugarMachine) {
		machine = sugarMachine;
	}

	@Override
	public void provideSugar() {
		machine.releaseSugar();
		if (machine.getCount() > 0) {
			machine.setState(machine.getNoMoneyState());
		} else {
			System.out.println("Sugar is sold out");
			machine.setState(machine.getSoldOutState());
		}
	}
}

public class WinnerState extends State {
	
	private SugarMachine machine;

	public WinnerState(SugarMachine sugarMachine) {
		machine = sugarMachine;
	}

	@Override
	public void provideSugar() {
		System.out.println("You are winner, you can get two sugars");
		machine.releaseSugar();
		if (machine.getCount() == 0) {
			machine.setState(machine.getSoldOutState());
		} else {
			machine.releaseSugar();
			if (machine.getCount() > 0) {
				machine.setState(machine.getNoMoneyState());
			} else {
				System.out.println("Sugar is sold out");
				machine.setState(machine.getSoldOutState());
			}
		}
	}
}

public class SoldOutState extends State {

	private SugarMachine machine;
	
	public SoldOutState(SugarMachine sugarMachine) {
		machine = sugarMachine;
	}

	@Override
	public void refillSugar() {
		System.out.println("Sugar is refilled again");
		machine.setState(machine.getNoMoneyState());
	}
}

public class SugarMachine {
	
	private State noMoneyState;
	private State hasMoneyState;
	private State soldOutState;
	private State winnerState;
	private State soldState;

	private State state;
	private int count;
	
	public SugarMachine(int numberOfSuagr) {
		count = numberOfSuagr;
		
		this.noMoneyState = new NoMoneyState(this);
		this.hasMoneyState = new HasMoneyState(this);
		this.soldState = new SoldState(this);
		this.winnerState = new WinnerState(this);
		this.soldOutState = new SoldOutState(this);
		this.state = soldOutState;
		
		if (count > 0) {
			this.state = noMoneyState;
		}
	}
	
	public void setState(State state) {
		this.state = state;
	}
	
	public void putMoney() {
		state.putMoney();
	}
	
	public void backMoney() {
		state.backMoney();
	}
	
	public void turnHandle() {
		if (state.turnHandle()) {
			state.provideSugar();
		}
	}
	
	public void refillSugar(int count) {
		this.count += count;
		state.refillSugar();
	}
	
	public void releaseSugar() {
		System.out.println("A sugar is rolling out");
		if (count > 0) {
			count--;
		}
	}

	public State getNoMoneyState() {
		return noMoneyState;
	}

	public State getHasMoneyState() {
		return hasMoneyState;
	}

	public State getSoldOutState() {
		return soldOutState;
	}

	public State getWinnerState() {
		return winnerState;
	}

	public State getSoldState() {
		return soldState;
	}
	
	public int getCount() {
		return count;
	}
}

public class PatternDemo {
	
	public static void main(String[] args) {
		SugarMachine machine = new SugarMachine(3);
		
		machine.backMoney();
		machine.turnHandle();
		
		machine.putMoney();
		machine.backMoney();
		
		//1
		machine.putMoney();
		machine.turnHandle();
		machine.turnHandle();
		
		//2
		machine.putMoney();
		machine.putMoney();
		machine.turnHandle();

		//3
		machine.putMoney();
		machine.turnHandle();

		//4
		machine.putMoney();
		machine.turnHandle();

		machine.refillSugar(1);
		//5
		machine.putMoney();
		machine.turnHandle();
	}
}

运行结果:

Error state, can't back money
Error state, turn handle no effect
Put money
Money back
Put money
A sugar is rolling out
Error state, turn handle no effect
Put money
Error state, can't put money
A sugar is rolling out
Put money
A sugar is rolling out
Sugar is sold out
Error state, can't put money
Error state, turn handle no effect
Sugar is refilled again
Put money
A sugar is rolling out
Sugar is sold out

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值