81 lines
3.5 KiB
Python
81 lines
3.5 KiB
Python
|
from abc import ABC, abstractmethod
|
|||
|
# интерфейс состояния
|
|||
|
class State(ABC):
|
|||
|
@abstractmethod
|
|||
|
def insert_coin(self): pass
|
|||
|
@abstractmethod
|
|||
|
def select_drink(self): pass
|
|||
|
@abstractmethod
|
|||
|
def dispense(self): pass
|
|||
|
# состояние ожидания монеты
|
|||
|
class WaitingForCoinState(State):
|
|||
|
def __init__(self, vending_machine): self.vending_machine = vending_machine
|
|||
|
def insert_coin(self):
|
|||
|
print("Монета принята")
|
|||
|
self.vending_machine.set_state(self.vending_machine.waiting_for_selection)
|
|||
|
def select_drink(self):
|
|||
|
print("Сначала вставьте монету")
|
|||
|
def dispense(self):
|
|||
|
print("Невозможно выдать напиток без оплаты")
|
|||
|
# состояние "Нет товаров"
|
|||
|
class OutOfStockState(State):
|
|||
|
def __init__(self, vending_machine): self.vending_machine = vending_machine
|
|||
|
def insert_coin(self): print("Нет товаров")
|
|||
|
def select_drink(self): print("Нет товаров")
|
|||
|
def dispense(self): print("Нет товаров")
|
|||
|
# состояние "Ожидание выбора"
|
|||
|
class WaitingForSelectionState(State):
|
|||
|
def __init__(self, vending_machine): self.vending_machine = vending_machine
|
|||
|
def insert_coin(self):
|
|||
|
print("Монета уже вставлена")
|
|||
|
def select_drink(self):
|
|||
|
print("Напиток выбран")
|
|||
|
self.vending_machine.set_state(self.vending_machine.dispensing)
|
|||
|
def dispense(self):
|
|||
|
print("Выберите напиток, прежде чем получить его")
|
|||
|
# состояние "Выдача товара"
|
|||
|
class DispensingState(State):
|
|||
|
def __init__(self, vending_machine): self.vending_machine = vending_machine
|
|||
|
def insert_coin(self): print("Идет выдача напитка")
|
|||
|
def select_drink(self): print("Идет выдача напитка")
|
|||
|
def dispense(self):
|
|||
|
if self.vending_machine.stock > 0:
|
|||
|
self.vending_machine.stock -= 1
|
|||
|
print("Напиток выдан")
|
|||
|
if self.vending_machine.stock == 0:
|
|||
|
print("Товар закончился")
|
|||
|
self.vending_machine.set_state(self.vending_machine.out_of_stock)
|
|||
|
else:
|
|||
|
self.vending_machine.set_state(self.vending_machine.waiting_for_coin)
|
|||
|
else:
|
|||
|
print("Товар закончился")
|
|||
|
self.vending_machine.set_state(self.vending_machine.out_of_stock)
|
|||
|
# контекст
|
|||
|
class VendingMachine:
|
|||
|
def __init__(self):
|
|||
|
self.stock = 0
|
|||
|
self.out_of_stock = OutOfStockState(self)
|
|||
|
self.waiting_for_coin = WaitingForCoinState(self)
|
|||
|
self.waiting_for_selection = WaitingForSelectionState(self)
|
|||
|
self.dispensing = DispensingState(self)
|
|||
|
self.state = self.out_of_stock
|
|||
|
def set_state(self, state): self.state = state
|
|||
|
def insert_coin(self): self.state.insert_coin()
|
|||
|
def select_drink(self): self.state.select_drink()
|
|||
|
def dispense(self): self.state.dispense()
|
|||
|
def refill(self, amount):
|
|||
|
self.stock += amount
|
|||
|
print(f"Товар пополнен. Запас: {self.stock}")
|
|||
|
if self.stock > 0:
|
|||
|
self.set_state(self.waiting_for_coin)
|
|||
|
|
|||
|
vending_machine = VendingMachine()
|
|||
|
vending_machine.refill(3)
|
|||
|
vending_machine.insert_coin()
|
|||
|
vending_machine.select_drink()
|
|||
|
vending_machine.dispense()
|
|||
|
vending_machine.select_drink()
|
|||
|
vending_machine.insert_coin()
|
|||
|
vending_machine.dispense()
|
|||
|
vending_machine.dispense()
|
|||
|
vending_machine.dispense()
|