Шаблон состояния в Java

Шаблон проектирования State (Состояние) является одним из поведенческих шаблонов проектирования. Шаблон проектирования State используется, когда объект изменяет свое поведение в зависимости от своего внутреннего состояния.

Шаблон проектирования State

Если нам нужно изменить поведение объекта на основе его состояния, мы можем иметь переменную состояния в объекте. Затем использовать блок условия if-else для выполнения разных действий в зависимости от состояния. Шаблон проектирования State используется для обеспечения систематического и слабо связанного способа достижения этого через реализации Контекста и Состояния. Класс Контекста является классом, который имеет ссылку на одну из конкретных реализаций Состояния. Контекст перенаправляет запрос к объекту состояния для обработки. Давайте разберем это на простом примере. Предположим, нам нужно реализовать пульт для телевизора с простой кнопкой для выполнения действия. Если состояние включено (ON), то телевизор будет включен, а если состояние выключено (OFF), то телевизор будет выключен. Мы можем реализовать это с помощью условия if-else, как показано ниже; TVRemoteBasic.java

package com.journaldev.design.state;

public class TVRemoteBasic {

	private String state="";
	
	public void setState(String state){
		this.state=state;
	}
	
	public void doAction(){
		if(state.equalsIgnoreCase("ON")){
			System.out.println("TV is turned ON");
		}else if(state.equalsIgnoreCase("OFF")){
			System.out.println("TV is turned OFF");
		}
	}

	public static void main(String args[]){
		TVRemoteBasic remote = new TVRemoteBasic();
		
		remote.setState("ON");
		remote.doAction();
		
		remote.setState("OFF");
		remote.doAction();
	}

}

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

Интерфейс шаблона состояния

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

package com.journaldev.design.state;

public interface State {

	public void doAction();
}

Реализации конкретных состояний шаблона состояния

В нашем примере у нас может быть два состояния – одно для включения телевизора и другое для его выключения. Поэтому мы создадим две конкретные реализации состояний для этих поведений. TVStartState.java

package com.journaldev.design.state;

public class TVStartState implements State {

	@Override
	public void doAction() {
		System.out.println("TV is turned ON");
	}

}

TVStopState.java

package com.journaldev.design.state;

public class TVStopState implements State {

	@Override
	public void doAction() {
		System.out.println("TV is turned OFF");
	}

}

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

Реализация контекста паттерна State

TVContext.java

package com.journaldev.design.state;

public class TVContext implements State {

	private State tvState;

	public void setState(State state) {
		this.tvState=state;
	}

	public State getState() {
		return this.tvState;
	}

	@Override
	public void doAction() {
		this.tvState.doAction();
	}

}

Обратите внимание, что Контекст также реализует State и хранит ссылку на свое текущее состояние, перенаправляя запрос к реализации состояния.

Программа тестирования паттерна State

Теперь давайте напишем простую программу для тестирования нашей реализации паттерна State для управления телевизором. TVRemote.java

package com.journaldev.design.state;

public class TVRemote {

	public static void main(String[] args) {
		TVContext context = new TVContext();
		State tvStartState = new TVStartState();
		State tvStopState = new TVStopState();
		
		context.setState(tvStartState);
		context.doAction();
		
		
		context.setState(tvStopState);
		context.doAction();
		
	}

}

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

Преимущества паттерна State

Преимущества использования шаблона состояния для реализации полиморфного поведения явно видны. Вероятность ошибок меньше, и очень легко добавить больше состояний для дополнительного поведения. Таким образом, наш код становится более надежным, легко поддерживаемым и гибким. Кроме того, шаблон состояния помогает избежать условной логики if-else или switch-case в данном сценарии. Шаблон состояния очень похож на шаблон стратегии; ознакомьтесь с Шаблон стратегии в Java. Вот и все по шаблону проектирования состояния в Java, надеюсь, вам понравилось.

Source:
https://www.digitalocean.com/community/tutorials/state-design-pattern-java