Подтвердить что ты не робот

Как правильно использовать шаблон состояния?

В моем опыте программирования я обнаружил несколько реализаций шаблона состояния и сделал несколько. Я видел, как они использовались в различных сценариях (в основном, пользовательский интерфейс и синтаксический анализ). Беда в том, что все они под давлением быстрого развития превратились в едва ремонтные и понятные куски кода. Я рассматриваю возможность реорганизации одного из них, но мне трудно найти хорошие ресурсы для этого онлайн. Существует много простых примеров государственного шаблона онлайн, но мне нужны дополнительные ресурсы.

Итак, я ищу:

  • Примеры общих ошибок, когда реализации государственной модели и избегайте их,
  • Примеры реального мира правильно выполненный шаблон состояния (например, в некоторые проекты/рамки с открытым исходным кодом)
  • Личный опыт с государством шаблон также приветствуется

Спасибо за ваше время

4b9b3361

Ответ 1

@Ivan: В Интернете имеется ряд ресурсов для Иерархических государственных машин (HSM). Миро Самек много писал об этом шаблоне дизайна и предлагает много полезной информации.

Некоторые статьи, которые должны представлять интерес:

Большое преимущество использования HSM над плоскими диаграммами состояний FSM, описанными Мили и Муром, заключается в том, что иерархия создает разделение ответственности. Под-состояниям необходимо обрабатывать только те условия, для которых они явно предназначены для обработки - необработанные события передаются в родительское состояние, если родительское состояние явно не предназначено для его обработки, тогда оно передается до следующего уровня родительский и т.д. Он позволяет создавать небольшие управляемые конечные машины, каждая из которых обслуживает одну цель - такую, которая может вписываться в один объект. По мере добавления новых функций или добавления новых классов им нужно только обрабатывать свою небольшую часть мира и передавать необработанные события своим родителям.

При правильной реализации вы получаете надежную программу с низкой циклической сложностью, которую легко модифицировать или обновлять по мере необходимости.

Ответ 2

Как вы, вероятно, читали, State Design Pattern полезен, когда состояние изменяет поведение какого-либо объекта, состав которого включает это состояние. Это подразумевает идею абстрактного класса State, интерфейса или перечисляемого типа - хотя и в зависимости от языка Duck Typing - это определяет любое общее поведение и/или требуемые методы.

Ключевые аспекты

В работе с шаблоном состояния есть два основных аспекта: перечисление и переход. Перечисление просто означает идентификацию множества возможных состояний (например, дней недели) или более абстрактно типов состояний (например, мета-состояний), таких как начало, окончание и промежуток для механизма рабочего процесса. Переход означает принятие решения о моделировании движения между состояниями, где это обычно выполняется путем захвата всех возможных переходов в табличном представлении (т.е. Конечный автомат) или сделать каждое государство известным своим возможным "переходы" в другие государства.

Обычно переходы идут рука об руку с мета-состояниями, потому что невозможно знать все состояния и отношения заблаговременно в такой динамической системе, где новые состояния и, следовательно, переходы могут быть добавлены во время выполнения. Кроме того, с переходным подходом определенное поведение - уведомления, например, становится частью перехода, а не самого состояния.

Примеры

Существует несколько сценариев, в которых я работал или обсуждал, где это средство использования:

  • Workflow
  • Противник компьютерных игр A.I.
  • Процесс оркестровки

В рабочем процессе я имею в виду что-то вроде jBPM. Системы, подобные этим, связаны с правильным вниманием, нужными людьми в нужное время. Обычно они отправляют много писем или другое уведомление. И процесс, который они представляют, нуждается в способности меняться по мере изменения организации, тогда как управляемые данные обычно изменяются гораздо медленнее.

Противник компьютерных игр A.I. сам объясняет. Не то, что я написал, но в разговоре с теми, у кого есть, эти системы обычно автономны. Другими словами, в отличие от рабочего процесса, игра обычно не имеет возможности изменять процесс, используемый для управления компьютерными противниками.

Процесс оркестровки похож на рабочий процесс, но ориентирован на системную интеграцию, а не на взаимодействие с людьми. Пример Apache Mule - пример. Здесь состояние может описывать состояние (например, запущено, в процессе, закончено) и тип (например, точка интеграции ftp, точка интеграции sql).

Заключение

В отличие от других ответов, я считаю, что инкапсуляция состояний - отличный способ управлять изменениями в программных системах. Совершенно хорошо, это облегчает эти изменения или позволяет пользователям делать это во время выполнения. Вы делаете компромисс большей гибкости в обмен на повышенную сложность реализации. Таким образом, такой подход, вероятно, не полезен, например, для корзины покупок, где поведение, вероятно, очень хорошо известно и не нравится изменять. С другой стороны, когда процесс может быть изменен, он очень хорошо подходит.

Ответ 3

Только мои 2 цента, государственный шаблон всегда становится трудно поддерживать, поскольку его трудно понять тем, кто его не закодировал. Обычно я отказываюсь от старого стандартного массива указателей функций/методов, как и в моем старом опыте С. Вы просто создаете массив из двух измерений указателей функций с состоянием/сигналом для строк/столбцов. Легче понять. у вас есть класс, который управляет этим, и вы делегируете другой класс для обработки сложности...

my2c

Ответ 4

В большинстве случаев состояния в структуре шаблонов состояний обрабатывают больше одного состояния (или подстанции состояния), что затрудняет их поддержку.

Если в каком-либо состоянии есть какой-либо выбор, он в основном обрабатывает более одного состояния.

Я занимаю много дисциплины, чтобы поддерживать чистоту состояний.

Возможным решением этого является создание более сложных состояний statemachines (HSM). Это делает его более читаемым на верхнем уровне, потому что ему приходится иметь дело с меньшим количеством состояний.

Ответ 5

посмотрите Конечный автомат. Практически каждый зрелый язык имеет свои хорошие примеры. Поскольку вы не указали свой предпочтительный язык, я дам вам пример С++: Boost FSM library. Скорее всего, это намного сложнее, чем вам нужно, но это может дать вам некоторые советы по дизайну.

Ответ 6

Итак, я ищу:

  • Примеры общих ошибок при реализации шаблона состояния и способах их устранения

Шаблон состояния плохо масштабируется. Представьте себе машину состояний с 10 состояниями и 10 различными типами переходов. Добавление нового состояния означает, что состояние должно определять все 10 переходов. Добавление нового перехода означает, что все 10 состояний должны определить его. Короче говоря, не используйте шаблон состояния, если ваш конечный автомат нестабилен и/или у вас много состояний/переходов.

  • Примеры правильного образа в реальном мире, выполненные правильно (как в некоторых проектах/рамках с открытым исходным кодом)

Правильно определите:-) Пример Java, приведенный в fooobar.com/questions/5866/..., относится к жизненному циклу JSF, но я думаю, что есть только один переход. Ни один из других ответов не цитирует ничего для государства.

  • Приветствуются личный опыт использования шаблона состояния.

В главе First Design Patterns используется пример машины Gumball для иллюстрации состояния. Это иронично, но каждый раз, когда они расширяют дизайн (добавление нового состояния или перехода), существует много повторяющегося кода (особенно для недействительных переходов в определенных состояниях). Кроме того, согласно тому, кто решает, что такое следующее состояние, отдельные классы состояний могут быть связаны друг с другом (межгосударственные зависимости). См. Объяснение в конце этого ответа: fooobar.com/questions/41085/....

В книге GoF упоминается, что альтернативы на основе таблиц имеют преимущества, а именно их регулярность. Изменение критериев перехода требует изменения таблицы (а не кода).

Ответ 7

Вы должны использовать шаблон состояния, если у вас другое поведение для каждого состояния. Возможно, вам нужно перенастроить переходы во время выполнения. Другая причина для его использования - вам, возможно, придется добавить несколько состояний позже.

Представьте себе настольную игру, такую ​​как Chinese Checkers, у вас разные государства GUI для выбора пешки, выберите целевой слот и так далее. В каждом штате графический интерфейс должен вести себя по-разному, некоторые входы должны обрабатываться другими, игнорируемыми. Использование простого переключателя/случая возможно, но шаблон состояния удобен по мере инкапсуляции логики, связанный с ним код. Это упрощает введение новых состояний, не затрагивая большинство/всех других состояний (в зависимости от того, кто ответственен за установку переходов: либо состояние знает свои исходящие переходы, либо они могут быть заданы во время выполнения, например, используя конструктор).

Как вы можете видеть в в этом примере, GuiController использует интерфейс IGuiState для изменения своего поведения по требованию. Здесь можно увидеть реализацию .

Основная ошибка заключается в использовании переключателя/футляра, когда вам нужно быть гибким. Поскольку косвенность занимает немного больше времени, я бы рекомендовал это для фиксированного количества довольно простых staates. Я должен реализовать довольно быстрый низкоуровневый сетевой протокол, который обычно накладывает большие накладные расходы.

Ответ 8

Я строю оценщик выражений, который имеет возможность оценивать множество элементов. Я нашел шаблон состояния очень полезным для различения того, что может и не может быть сделано для набора в зависимости от его состояния. т.е.: открытый, закрытый, неактивный, активный ect. FSM очень легко нарисовать и уменьшить сложность кода, исключив необходимость в огромных блоках операторов ifelse, чтобы определить, что должна делать функция в зависимости от ее закрытых атрибутов. Это делает эти условия более явными, превращая условия в классы. Это один из моих любимых шаблонов.