Что такое паттерн состояние
Что проверяют
Умеете ли вы превращать разросшуюся лесенку условий по полю статуса в явную машину состояний. Второй слой вопроса неизбежен: чем это отличается от стратегии, у которой на схеме всё выглядит точно так же.
Как отвечать
Паттерн позволяет объекту менять поведение при изменении внутреннего состояния так, будто он сменил класс. Каждое состояние это отдельный объект с общим набором методов, контекст делегирует ему вызовы и подменяет его при переходе.
class Draft:
def publish(self, doc): doc.state = Review()
def archive(self, doc): doc.state = Archived()
class Review:
def publish(self, doc): doc.state = Published()
def archive(self, doc): raise InvalidTransition
class Document:
def __init__(self):
self.state = Draft()
def publish(self):
self.state.publish(self)В Python отдельный абстрактный базовый класс обычно не нужен: достаточно одинакового набора методов, а для статической проверки берут протокол. Для простых случаев честнее не плодить классы, а описать переходы таблицей: словарь, где ключ это пара из текущего состояния и события, а значение следующее состояние.
Стоит проговорить три вещи: где живут переходы, что происходит при недопустимом переходе (исключение, а не молчаливое игнорирование) и как состояние переживает перезапуск процесса.
Где спотыкаются
Не могут отличить от стратегии. Схема совпадает, намерение разное: стратегию выбирает клиент снаружи и она не знает о других вариантах, а состояния переключают сами себя и знают о соседях по графу.
Разбрасывают переходы: часть в контексте, часть внутри состояний, часть в вызывающем коде. На вопрос, какие переходы вообще допустимы, никто не может ответить, не прочитав весь модуль. Граф должен быть описан в одном месте.
Хранят в базе объект состояния или его экземпляр в сессии. В хранилище должна уезжать строка или короткий код, а объект собирается при загрузке. Иначе миграция на новый набор состояний превращается в разбор сериализованного мусора.