状态模式
概念
状态模式允许对象在内部状态改变时,改变它的行为。对象好像看起来修改了它的类。
这个模式将状态封装成了独立的类,并将动作委托到当前状态的对象。
- 状态模式用类代表不同的状态
- Context会将行为委托到当前对象
- 状态转换可以由State类控制或者Context控制
- 使用状态模式通常会导致程序中类的数目大大增加
- State可以被多个Context实例共享
策略模式区别
- 以状态模式而言,根据不同状态执行不同的行为,客户端对状态对象无需过多的了解。
- 对于策略对象而言,客户端通常要指定Context使用哪一个策略对象。
示例
代码语言:javascript复制/**
* 糖果机 状态接口
* @author huangy on 2019-06-08
*/
public interface State {
/**
* 投币
*/
void insertQuarter();
/**
* 退钱
*/
void ejectQuarter();
/**
* 试着转动曲柄
*/
void turnCrank();
/**
* 发放糖果
*/
void dispense();
}
代码语言:javascript复制/**
* @author huangy on 2019-06-08
*/
public class HasQuarterState implements State {
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("HasQuarterState insertQuarter");
}
@Override
public void ejectQuarter() {
System.out.println("HasQuarterState ejectQuarter");
}
@Override
public void turnCrank() {
System.out.println("HasQuarterState turnCrank");
// 状态里面可以改变状态
gumballMachine.setState(gumballMachine.soldState);
}
@Override
public void dispense() {
System.out.println("HasQuarterState dispense");
}
}
代码语言:javascript复制/**
* @author huangy on 2019-06-08
*/
public class NoQuarterState implements State {
GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("NoQuarterState insertQuarter");
gumballMachine.setState(gumballMachine.hasQuqrterState);
}
@Override
public void ejectQuarter() {
System.out.println("NoQuarterState ejectQuarter");
}
@Override
public void turnCrank() {
System.out.println("NoQuarterState turnCrank");
}
@Override
public void dispense() {
System.out.println("NoQuarterState dispense");
}
}
代码语言:javascript复制/**
* @author huangy on 2019-06-08
*/
public class SoldOutState implements State {
GumballMachine gumballMachine;
public SoldOutState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("SoldOutState insertQuarter");
}
@Override
public void ejectQuarter() {
System.out.println("SoldOutState ejectQuarter");
}
@Override
public void turnCrank() {
System.out.println("SoldOutState turnCrank");
}
@Override
public void dispense() {
System.out.println("SoldOutState dispense");
}
}
代码语言:javascript复制/**
* @author huangy on 2019-06-08
*/
public class SoldState implements State {
GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("SoldState insertQuarter");
}
@Override
public void ejectQuarter() {
System.out.println("SoldState ejectQuarter");
}
@Override
public void turnCrank() {
System.out.println("SoldState turnCrank");
}
@Override
public void dispense() {
System.out.println("SoldState dispense");
}
}
代码语言:javascript复制/**
* 糖果机 (Context)
* @author huangy on 2019-06-08
*/
public class GumballMachine {
/**
* 糖果机的状态
*/
State soldOutState;
State noQuqrterState;
State hasQuqrterState;
State soldState;
// 当前状态
State state = soldOutState;
// 糖果数目
int count = 0;
public GumballMachine(int count) {
this.count = count;
soldOutState = new SoldOutState(this);
noQuqrterState = new NoQuarterState(this);
hasQuqrterState = new HasQuarterState(this);
soldState = new SoldState(this);
if (count > 0) {
// Context里面可以改变状态
state = noQuqrterState;
}
}
public void insertQuarter() {
state.insertQuarter();
}
public void ejectQuarter() {
state.ejectQuarter();
}
public void turnCrank() {
state.turnCrank();
state.dispense();
}
public void setState(State state) {
this.state = state;
}
public void releaseBall() {
System.out.println("releaseBall");
if (count != 0) {
count--;
}
}
@Override
public String toString() {
return "GumballMachine{"
"state=" state
", count=" count
'}';
}
}
代码语言:javascript复制public class DemoTest {
public static void main(String[] args) {
GumballMachine gumballMachine = new GumballMachine(5);
System.out.println(gumballMachine);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
System.out.println(gumballMachine);
}
}