certain-design-patterns/state.py

81 lines
3.5 KiB
Python
Raw Normal View History

2025-02-07 12:10:20 +03:00
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()