定义:允许对象在内部状态改变时改变它的行为。对象看起来好像修改了它的类。状态模式将状态封装成独立的类,并将动作委托到代表当前状态的对象。
看个类图:
来一个具体的例子:
public interface State{
void insertQuarter():
void ejectQuarter();
void turnCrank();
void dispense();
}
public class NoQuarterState implents State{
GumballMachine gumballMachine;
public NoQuarterState ( GumballMachine gumballMachine ){
this. gumballMachine= gumballMachine;
}
public void insertQuarter(){
System.out.println("你放入了钱");
gumballMachine.setState(gumballMachine.getHasQuarterState())
}
public void ejectQuarter(){
System.out.println("你没有钱");
}
public void turnCrank(){
System.out.println("白转没有钱");
}
public void dispense(){
System.out.println("你需要先给钱");
}
}
//糖果机
public class GumballMachine{
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
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);
this.count=numberGumballs;
if(numberGumballs > 0 ){
state = niQuarterState;
}
}
//四个行为动作很容易实现了,我们只是委托到当前状态
public void insertQuarter(){
state.insertQuarter();
}
public void ejectQuarter(){
state.ejectQuarter();
}
public void turnCrank(){
state.turnCrank();
state.dispense();
//我们不需要在机器中准备一个发放糖果的方法,因为这是一个内部动作
//用户不可以直接要求发放糖果。我们是在状态对象的turnCrank()中调用
}
void setState(Satet state){
this.state=state;
}
void releaseBall(){
System.out.println("出糖了");
if(count ! = 0){
count--;
}
}
}
public class HasQuarterState implments State{
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine){
this.gumballMachine=gumballMachine;
}
public void insertQuarter(){
System.out.println("你不能再放钱了");
}
public void ejectQuarter(){
System.out.println("退给你");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
public void turnCrank(){
System.out.println("你转动手柄");
gumballMachine.setState(gumballMachine.getSoldState());
}
public void dispense(){
System.out.println("没有糖果发放");
}
}
//售出状态
public class SoldState implments State{
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine){
this.gumballMachine=gumballMachine;
}
public void insertQuarter(){
System.out.println("等等刚给了你糖果");
}
public void ejectQuarter(){
System.out.println("你已经转手柄了");
}
public void turnCrank(){
System.out.println("你白转动手柄不会给你两个");
}
public void dispense(){
gumballMachine.releaseBall();
if(gumballMachine.getCount() > 0){
gumballMachine.setState(gumballMachine.getNoQuarterState() );
}else{
System.out.println("卖完了");
gumballMachine.setState(gumballMachine.getSoldOutState() );
}
}
}
//售完的状态
public class SoldOutState implments State{
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine){
this.gumballMachine=gumballMachine;
}
public void insertQuarter(){
System.out.println("糖果已经卖完了");
}
public void ejectQuarter(){
System.out.println("你不能退这没有糖果");
}
public void turnCrank(){
System.out.println("你白转动手柄没有糖果");
}
public void dispense(){
System.out.println("没有糖果");
}
}
总结一把:状态模式的类图和策略者模式的类图是一样的,二者的区别在于意图不同,策略模式通常会用行为或算法来配置Context类,状态模式允许Context随着状态的改变而改变行为。而任何的改变都是定义好的。当我的Context对象被创建之后,建我可以告诉他们从什么时候开始,然后他们会随着时间的流逝改变自己的状态。