状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
(1)context是一个类,它可以拥有一些那边状态。在例子中,gumballMachine就是这个context
(2)state接口定义了一个所有具有状态的共同接口;任何状态都实现这个相同的接口,这样一来,状态之间可以互相替换
(3)不管是在什么时候,只要有人调用context的request()方法,它就会被委托到状态来处理。
(4)concreteStateA(具体状态)处理来自context的请求,每个concreteStateA都提供了它自己对于请求的实现。所以,当context改变状态时行为也跟着改变。
下面例子是以自动贩卖机为背景,
状态:投币足够 投币不足够 购买成功 和 售罄 四个状态
每个状态执行的动作:投钱 退钱 转动曲柄购买 购买货物
1、定义状态接口
/**
* 定义所有的状态接口。这些状态映射到贩卖机上可能发生的动作
*
*/
public interface State {
/**
* 投钱
*/
void insertQuarter();
/**
* 退钱
*/
void ejectQuarter();
/**
* 转动曲柄
*/
void turnCrank();
/**
* 贩卖货物
*/
void dispense();
}
2、状态实现1
/**
* 贩卖机出货
*/
public class SoldState implements State{
GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("已完成出货!️");
}
@Override
public void ejectQuarter() {
System.out.println("已完成出货,不支持退钱!");
}
@Override
public void turnCrank() {
System.out.println("已完成出货,不支持转动购买!");
}
@Override
public void dispense() {
gumballMachine.releaseBall();
if(gumballMachine.getCount() > 0){
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("货已经售罄!");
gumballMachine.setState(gumballMachine.soldOutState);
}
}
}
3、状态实现2
/**
* 贩卖机已售罄状态
*/
public class SoldOutState implements State{
GumballMachine gumballMachine;
public SoldOutState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("货已售罄,不支持投币!");
}
@Override
public void ejectQuarter() {
System.out.println("货已售罄,不支持退钱!");
}
@Override
public void turnCrank() {
System.out.println("货已售罄,不支持购买!");
}
@Override
public void dispense() {
System.out.println("货已售罄,不支持贩卖!");
}
}
4、状态实现3
/**
* 投币不够状态
*
*/
public class NoQuarterState implements State{
GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("投入了足够的钱!");
gumballMachine.setState(gumballMachine.getHasQuarterState());
}
@Override
public void ejectQuarter() {
System.out.println("你没有投钱!");
}
@Override
public void turnCrank() {
System.out.println("没有投入足够的钱,转动后没有货物出来!");
}
@Override
public void dispense() {
System.out.println("你需要先投币!");
}
}
5、状态实现4
/**
* 投币足够状态
*/
public class HasQuarterState implements State {
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("投币已足够!");
}
@Override
public void ejectQuarter() {
System.out.println("退钱!");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
@Override
public void turnCrank() {
System.err.println("正在出货中");
gumballMachine.setState(gumballMachine.getSoldState());
}
@Override
public void dispense() {
System.out.println("已出货。");
}
}
6、context类
/**
* 贩卖机类
*/
public class GumballMachine {
State soldState;
State soldOutState;
State noQuarterState;
State hasQuarterState;
State state = soldOutState;
int count = 0;
public GumballMachine(int numberGumball) {
soldState = new SoldState(this);
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
this.count = numberGumball;
if(numberGumball > 0){
state = noQuarterState;
}
}
public void insertQuarter(){
state.insertQuarter();
}
public void ejectQuarter(){
state.ejectQuarter();
}
public void turnCrank(){
state.turnCrank();
state.dispense();
}
public void releaseBall(){
System.out.println("货物已售出!");
if(count != 0){
count = count - 1;
}
}
public State getSoldState() {
return soldState;
}
public void setSoldState(State soldState) {
this.soldState = soldState;
}
public State getSoldOutState() {
return soldOutState;
}
public void setSoldOutState(State soldOutState) {
this.soldOutState = soldOutState;
}
public State getNoQuarterState() {
return noQuarterState;
}
public void setNoQuarterState(State noQuarterState) {
this.noQuarterState = noQuarterState;
}
public State getHasQuarterState() {
return hasQuarterState;
}
public void setHasQuarterState(State hasQuarterState) {
this.hasQuarterState = hasQuarterState;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
7、测试类
public class MainTest {
public static void main(String[] args) {
GumballMachine gumballMachine = new GumballMachine(5);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
System.err.println("目前还省:" + gumballMachine.getCount());
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
System.err.println("目前还省:" + gumballMachine.getCount());
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
System.err.println("目前还省:" + gumballMachine.getCount());
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
System.err.println("目前还省:" + gumballMachine.getCount());
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
System.err.println("目前还省:" + gumballMachine.getCount());
gumballMachine.ejectQuarter();
gumballMachine.turnCrank();
}
}