Шаблон проектирования Состояние (State)

Пятый в серии шаблон — Состояние.

Суть — изменение поведения объекта в зависимости от состояния, в котором оно находится.

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

А я приведу несколько иной пример, более упрощенный.

Предположим у нас есть объект собачка, которая может быть в 3 состояниях — спящем, играющем и обедающим. И наша собачка будет переходить из одного состояния в другое при взаимодействии с ней (тап на экран в андроиде). Перейдем от слов к коду.

Для разных состояний нам понадибится интерфейс.

Будем вызывать событие, параметром получать некий контекст собачки. Также нам понадобится метод, который будет возвращать картинку собачки.

Теперь создадим 3 имплементации для спящей, играющей и обедающей собачки.

В методе взаимодействия выставляем следующее состояние — играющее.

После того как собачка поиграла, пусть поест (context.setDogState(new EatDogState());)

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

При создании контекста сразу проставим первое состояние сна, изображение состояния будем брать из интерфейса (второй метод DogState), также дадим внешним классам возможность взаимодействовать с собачкой и менять ее состояние.

Чтобы стало понятней давайте посмотрим на разметку главного экрана.

Здесь только изображение, по айдишнику будем менять картинку. Теперь сам класс экрана.

Итак, мы инициализируем изображение, создаем контекст собачки (там сразу проставляется состояние сна и проставляется значение изображения). После чего устанавливаем начальное изображение и проставляем картинке собачки обработчик нажатия. При каждом касании на собачку она будет менять свое состояние, после этого будем брать ресурс изображения и отображать собачку в новом состоянии.

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

Плюсы шаблона — инкапсулирование данных состояния, переход из одного в другой, вместо огромной портянки if else if else / switch case case case.. которая захламляет конечный класс. Также всегда можно легко и просто менять цепочку состояний.

Минусы — большое количество мелких классов, но в этом и суть ООП.

Запись опубликована в рубрике Программирование Android, Программирование Java. Добавьте в закладки постоянную ссылку.