状态模式

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

 

(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();
    
  }

}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值