定义
状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了它的类。
状态模式的实现方法是,定义一个state接口,在这个接口中,机器的每一个动作都对应一个方法。为机器的每个状态实现状态类,这些类负责在对应的状态下进行机器的行为。
优点
类图
类图
python代码实现
from abc import abstractmethod
import random
class State:
def __init__(self,gumball_machine):
self.gumball_machine = gumball_machine
@abstractmethod
def insert_quarter(self):
pass
@abstractmethod
def eject_quarter(self):
pass
@abstractmethod
def turn_crank(self):
pass
@abstractmethod
def dispense(self):
pass
class SoldState(State):
def insert_quarter(self):
print("SoldState:Please wait,we are already giving you a gumball")
def eject_quarter(self):
print("SoldState:Sorry,you already turned the crank")
def turn_crank(self):
print("SoldState:Turning twice doesn't get you another gumball!")
def dispense(self):
self.gumball_machine.release_ball()
if self.gumball_machine.get_number_gumball() > 0:
self.gumball_machine.set_state(self.gumball_machine.get_no_quarter_state())
else:
self.gumball_machine.set_state(self.gumball_machine.get_sold_out_state())
class WinnerState(State):
def insert_quarter(self):
print("WinnerState:Please wait,we are already giving you a gumball")
def eject_quarter(self):
print("WinnerState:Sorry,you already turned the crank")
def turn_crank(self):
print("WinnerState:Turning twice doesn't get you another gumball!")
def dispense(self):
print("WinnerState:You are a Winner!You get two gumballs for your quarter.")
self.gumball_machine.release_ball()
if self.gumball_machine.get_number_gumball() <= 0:
self.gumball_machine.set_state(self.gumball_machine.get_sold_out_state())
else:
self.gumball_machine.release_ball()
if self.gumball_machine.get_number_gumball() > 0:
self.gumball_machine.set_state(self.gumball_machine.get_no_quarter_state())
else:
self.gumball_machine.set_state(self.gumball_machine.get_sold_out_state())
class SoldOutState(State):
def insert_quarter(self):
print("SoldOutState:We don't have storage gumball in the machine!")
def eject_quarter(self):
print("SoldOutState:You haven't inserted a quarter!")
def turn_crank(self):
print("SoldOutState:You turned,but there's no quarter")
def dispense(self):
print("SoldOutState:You need to pay first")
class NoQuarterState(State):
def insert_quarter(self):
print("NoQuarterState:You insert a quarter!")
self.gumball_machine.set_state(self.gumball_machine.get_has_quarter_state())
def eject_quarter(self):
print("NoQuarterState:You haven't inserted a quarter!")
def turn_crank(self):
print("NoQuarterState:You turned,but there's no quarter")
def dispense(self):
print("NoQuarterState:You need to pay first")
class HasQuarterState(State):
def insert_quarter(self):
print("HasQuarterState:You Can't insert another quarter!")
def eject_quarter(self):
print("HasQuarterState:Quarter returned!")
self.gumball_machine.set_state(self.gumball_machine.get_no_quarter_state())
def turn_crank(self):
print("HasQuarterState:You turned...")
num = random.randint(0, 9)
gumball_cnt = self.gumball_machine.get_number_gumball()
if num == 0 and gumball_cnt > 1:
self.gumball_machine.set_state(self.gumball_machine.get_winner_state())
else:
self.gumball_machine.set_state(self.gumball_machine.get_sold_state())
def dispense(self):
print("HasQuarterState:No gumball dispensed")
class GumballMachine:
def __init__(self,number_gumball):
self.number_gumball = number_gumball
self.has_quarter_state = HasQuarterState(self)
self.no_quarter_state = NoQuarterState(self)
self.sold_out_state = SoldOutState(self)
self.winner_state = WinnerState(self)
self.sold_state = SoldState(self)
if number_gumball > 0:
self.state = self.no_quarter_state
else:
self.state = self.sold_out_state
def __str__(self):
return "GumballMachine:"+str(self.number_gumball)+" gumbals"
def get_number_gumball(self):
return self.number_gumball
def get_winner_state(self):
return self.winner_state
def get_has_quarter_state(self):
return self.has_quarter_state
def get_no_quarter_state(self):
return self.no_quarter_state
def get_sold_out_state(self):
return self.sold_out_state
def get_sold_state(self):
return self.sold_state
def set_state(self,state):
self.state = state
def release_ball(self):
if self.number_gumball > 0:
print("A gumball comes rolling out the slot...")
self.number_gumball -= 1
else:
print("No gumball to release")
def insert_quarter(self):
self.state.insert_quarter()
def eject_quarter(self):
self.state.eject_quarter()
def turn_crank(self):
self.state.turn_crank()
self.state.dispense()
def test_state():
machine = GumballMachine(2)
print("======================")
print(machine)
machine.insert_quarter()
machine.turn_crank()
print("======================")
print(machine)
machine.insert_quarter()
machine.turn_crank()
print("======================")
print(machine)
machine.insert_quarter()
machine.turn_crank()
if __name__ == "__main__":
test_state()