HEAD FIRST设计模式-状态模式

定义

状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了它的类。
状态模式的实现方法是,定义一个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()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值