定义
允许对象在内部转态改变时改变它的行为,对象看起来好像修改了它的类。
使用场景
- 对象的行为取决于它的状态,并且它会在运行时根据状态改变行为
- 大量的操作会引入很多依赖对象状态的条件语句,对象的状态可由一个或多个枚举常量表示,并且许多操作通常包含相同的条件结构。 状态模式将每个条件分支放在单独的类中。 这使我们可以将对象的状态视为一个对象,而且此对象可以独立于其他对象进行变化。
例子
如下是一个糖果贩卖机的状态转换图,投入0.25元转动曲柄可以获得糖果。
Paste_Image.png
首先定义各种状态,并且实现各种状态的方法,如投币、拿回币、转动曲柄、分发糖果;有些状态的方法其实是无效的:
public interface State{
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();
}
// 投入硬币的状态
public class HasQuarterState implements State{
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
public void insertQuarter(){
System.out.println("You can not insert another quarter");
}
public void ejectQuarter(){
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
public void turnCrank(){ // 摇动曲柄
System.out.println("You turned...");
gumballMachine.setState(gumballMachine.getSoldState());
}
public void dispense(){
System.out.println(" No gumball dispensed");
}
}
// 转动曲柄 销售状态
public class SoldState implements State{
GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
public void insertQuarter(){
System.out.println("Please wait, we are already giving you a gumball");
}
public void ejectQuarter(){
System.out.println("Sorry, you have turned the crank");
}
public void turnCrank(){ // 摇动曲柄
System.out.println("Turing twice doesn't get you another gumball");
}
public void dispense(){
gumballMachine.releaseBall();
if(gumballMachine.getCount() > 0){
gumballMachine.setState(gumballMachine.getNoQuarterState());
}else{
System.out.println("out of gumballs");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}
// NoQuarterState SoldOutState
糖果机的实现:
public class GumballMachine{
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State state = soldState;
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 = 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;
}
}
// getNoQuarterState等各种getter
}
分析
状态模式:封装基于状态的行为,并将行为委托到当前状态。
策略模式:将可以互换的行为封装起来,然后使用委托的方法决定使用哪一个行为
网友评论