Аннотация:
В случаях ветвления алгоритма или выполнения различных действий в зависимости от состояния применяются операторы if…else, switch…case..default и подобные им. Последовательности таких конструкций усложняют поддержку кода и отрицательно влияют на масштабируемость приложения. При необходимости добавить новые возможности требуется добавить еще один условный оператор, причем иногда в нескольких местах, что приводит к ошибкам.
Решить данную проблему позволяют сразу несколько паттернов, среди которых выделяется Состояние.
МН>Авторы: МН> Михаил Новиков
МН>Аннотация: МН>В случаях ветвления алгоритма или выполнения различных действий в зависимости от состояния применяются операторы if…else, switch…case..default и подобные им. Последовательности таких конструкций усложняют поддержку кода и отрицательно влияют на масштабируемость приложения. При необходимости добавить новые возможности требуется добавить еще один условный оператор, причем иногда в нескольких местах, что приводит к ошибкам. МН>Решить данную проблему позволяют сразу несколько паттернов, среди которых выделяется Состояние.
Статья интересная, но проблему эта реализация паттерна не решает.
Предположим, что надо вставить новое состояние между вторым и третьим. Для этого придется модифицировать код второго состояния. А если ещё кроме Next требуется Back, то тогда ещё и код третьего.
Проще сделать список объектов, и виджет будет просто передвигаться по списку. Таким образом не пришлось бы переписывать код состояний. Состояния вообще не должны знать кто идет после них.
И добавление нового состояние будет проще: всего лишь в списков нужном месте добавить код создания нового состояния.
А не встречалась ли вам ситуация, когда поведение экземпляра класса состояния зависит от данных полученных в предыдущем состоянии?
То есть событие, которое переключает состояние, содержит ещё и параметры, которые запоминаются и могут быть использованы другими состояними.
Или такой подход противоречит идее шаблона?
Во-первых, технический вопрос. В процедуре смены состояний мы каждый раз подписываемся на событие.
А отписываться от события старого объекта не надо? Не будет ли событие вызываться многократно после нескольких прохождений по цепочке?
Ну и потом, коллеги уже высказали справедливую критику, что такая реализация не является гибкой. Вообще говоря состояния и переходы между ними представляются произвольным графом, и только в редчайших случаях он вырождается в цепочку. Решение, какое состояние будет следующим, часто должно приниматься динамически на основе многих факторов.
Гораздо более интересна реализация например графического редактора, где состоянием является объект, принимающий события от мышки. В зависимости от выделенного графического инструмента события от мышки перенаправляются соответствующему объекту состояния, который кстати сказать ещё и может сам отрисовывать поверхность так, как это целесообразно при работе с выделенным инструментом.
Например, если мы рисуем прямую линию (отрезок), то в OnMouseMove нужно рисовать "временную" линию, соединяющую уже существующую точку и курсор мышки.
Здравствуйте, Valеntin, Вы писали:
V>То есть событие, которое переключает состояние, содержит ещё и параметры, которые запоминаются и могут быть использованы другими состояними.
В таком случае "параметры" должны быть частью "другого" состояния (то етсь копироваться в него).
... << RSDN@Home 1.2.0 alpha rev. 643>>
Now playing: «Тихо в лесу…»
Help will always be given at Hogwarts to those who ask for it.
Замечение к разделу "Enum State". Пример будет адекватно работать только при одном экземпляре класса Widget. Во-первых, дело в том, что перечисления в Java являются статическими элементами: если создать два экземпляра класса Widget, перевести оба в одно и тоже состояние, к примеру, STATEA, то далее любое действие над любым из экземпляров Widget будет отражаться на обоих экземплярах. Во-вторых, в примере почему-то не показано, что при переходе необходимо снять подписку с предыдущего состояния методом removeObserver.