Skip to main content

状态模式

Published: 2020-11-18

使用场景 #

状态是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为。

该模式将与状态相关的行为抽取到独立的状态类中, 让原对象将工作委派给这些类的实例, 而不是自行进行处理。

抽象状态类 #

定义所有需要实现的接口。

class State {
 public:
  virtual ~State() {}
  virtual void insertQuarter() = 0;
  virtual void ejectQuarter() = 0;
  virtual void turnCrank() = 0;
  virtual void dispense() = 0;
  virtual string toString() = 0;
};

具体状态子类 #

具体状态子类:

  • 包含场景类,在合适阶段,切换场景类里的状态;
  • 实现此状态可以完成的功能。
class NoQuarterState : public State {
 public:
  explicit NoQuarterState(GumballMachine *gumball_machine);
  virtual ~NoQuarterState();
  virtual void insertQuarter();
  virtual void ejectQuarter();
  virtual void turnCrank();
  virtual void dispense();
  virtual string toString();
 private:
  GumballMachine *gumball_machine_;
};

void NoQuarterState::insertQuarter() {
  cout << "You inserted a quarter" << endl;
  gumball_machine_->setState(gumball_machine_->has_quarter_state());
}

void NoQuarterState::ejectQuarter() {
  cout << "You haven't inserted a quarter" << endl;
}

void NoQuarterState::turnCrank() {
  cout << "You turned, but there's no quarter" << endl;
}

void NoQuarterState::dispense() {
  cout << "You need to pay first" << endl;
}

string NoQuarterState::toString() {
  return "waiting for quarter";
}

场景类 #

场景类中:

  • 包含所有的状态子类;
  • 包含一个抽象状态类,指向某一个具体的状态子类。
GumballMachine::GumballMachine(int number_gumballs) : count_(number_gumballs), state_(sold_out_state_) {

  sold_out_state_    = new SoldOutState(this);
  no_quarter_state_  = new NoQuarterState(this);
  has_quarter_state_ = new HasQuarterState(this);
  sold_state_        = new SoldState(this);

  if (count_ > 0) {
    state_ = no_quarter_state_;
  }
}

void GumballMachine::insertQuarter() {
  state_->insertQuarter();
}

void GumballMachine::ejectQuarter() {
  state_->ejectQuarter();
}

void GumballMachine::turnCrank() {
  state_->turnCrank();
  state_->dispense();
}

void GumballMachine::releaseBall() {
  cout << "A gumball comes rolling out the slot..." << endl;
  if (count_ != 0) {
    count_--;
  }
}

void GumballMachine::refill(int count) {
  count_ = count;
  state_ = no_quarter_state_;
}

Reference #

http://dreamrunner.org/blog/2014/05/04/%E6%B5%85%E8%B0%88%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F13/

https://www.jianshu.com/p/dc59262dc646


Next: 单例模式
Previous: STL体系结构与内核分析