[Design Pattern] 스테이트 패턴(State Pattern)
Posted: Updated:
자바 디자인 패턴 스터디를 하며 ‘Java 객체 지향 디자인 패턴’ 교재를 정리한 글입니다.
스테이트 패턴(State Pattern)
- 어떤 행위를 수행할 때 상태에 행위를 수행하도록 위임
- 시스템의 각 상태를 클래스로 분리해 표현
- 각 클래스에서 수행하는 행위들을 메서드로 구현
- 외부로부터 캡슐화를 위해 인터페이스를 만듦
스테이트 패턴 컬레보레이션
- State 인터페이스
- 모든 상태에 공통인 인터페이스 제공
- 실체화 시 상태 클래스를 교체하며 사용할 수 있음
- State 인터페이스 구현 클래스
- Context 클래스로부터 요청받은 작업을 각자의 방식으로 실제 실행
- 다음 상태를 결정해 상태 변경 요청
- Context 클래스
- State를 이용
- 시스템의 상태를 나타내는 상태 변수(state)와 상태를 구성하는 여러 변수가 있음
- 상태를 바꿀 수 있는 메서드(setState) 제공
- 실제 행위를 실행하지 않고 해당 상태 객체에 행위 실행 위임
상태 머신 다이어그램
- UML에서 상태와 상태 변화를 모델링하는 도구
예시: 형광등 만들기
2가지 상태만 존재할 때 구현
- 형광등이 꺼져 있을 때 외부에서 On 버튼을 누르면 형광등이 켜짐
- 형광등이 켜져 있을 때 Off 버튼을 누르면 꺼짐
- 켜져 있을 때 On 버튼을 누르거나, 꺼져 있을 때 Off 버튼을 누르면 변화가 없음
- 형광등의 상태를 표현하는 상수 정의
전체 코드
public class Light {
private static int ON = 0;
private static int OFF = 1;
private int state;
public Light() {
state = OFF;
}
public void on_button_pushed() {
if (state == ON) {
System.out.println("반응 없음");
}
else {
System.out.println("Light On!");
state = ON;
}
}
public void off_button_pushed() {
if (state == OFF) {
System.out.println("반응 없음");
}
else {
System.out.println("Light Off!");
state = ON;
}
}
}
public class Main {
public static void main(String[] args) {
Light light = new Light();
light.off_button_pushed();
light.on_button_pushed();
light.off_button_pushed();
}
}
출력
반응 없음
Light On!
Light Off!
스테이트 패턴으로 구현
- 상태를 클래스로 분리해 캡슐화
- 상태에 의존적인 행위를 상태 클래스에 두어 특정 상태에 따라 행위가 구현되도록 함
- 상태 객체를 싱글턴으로 만들어 메모리 절약
- 스트래티지 패턴과 유사
Light
클래스에서 상태 클래스에 작업 위임
전체 코드
public interface State {
public void on_button_pushed(Light light);
public void off_button_pushed(Light light);
}
public class ON implements State{
private static ON on = new ON();
private ON() { }
public static ON getInstance() {
return on;
}
@Override
public void on_button_pushed(Light light) {
System.out.println("반응 없음");
}
@Override
public void off_button_pushed(Light light) {
System.out.println("Light Off!");
light.setState(OFF.getInstance());
}
}
public class OFF implements State {
private static OFF off = new OFF();
private OFF() { }
public static OFF getInstance() {
return off;
}
@Override
public void on_button_pushed(Light light) {
System.out.println("Light On!");
light.setState(ON.getInstance());
}
@Override
public void off_button_pushed(Light light) {
System.out.println("반응 없음");
}
}
public class Light {
private State state;
public Light() {
state = OFF.getInstance();
}
public void setState(State state) {
this.state = state;
}
public void on_button_pushed() {
state.on_button_pushed(this);
}
public void off_button_pushed() {
state.off_button_pushed(this);
}
}
public class Main {
public static void main(String[] args) {
Light light = new Light();
light.off_button_pushed();
light.on_button_pushed();
light.off_button_pushed();
}
}
출력
반응 없음
Light On!
Light Off!
댓글남기기