디자인 패턴 – 스테이트 패턴

스테이트 패턴: 상태를 캡슐화하는 패턴

상태 머신 다이어그램: 상태와 상태 변화를 모델링하는 도구
(상태: 객체가 가질 수 있는 어떤 조건이나 상황)

기존 코드: 형광등의 ON버튼을 누르면 켜지고, OFF 버튼을 누르면 꺼지는 코드

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=OFF;
		}
	}
}

public class Client{
	public static void main(String[] args) {
		Light light=new Light();
		light.off_button_pushed();
		light.on_button_pushed();
		light.off_button_pushed();
	}
}

문제점: 새로운 상태인 ‘Sleeping’이 오면 기존 코드를 수정해야 된다. 만약 상태가 한 개만 존재하면 조건문이 없었지만, 상태가 추가되면 조건문이 생겨 코드를 수정해야 된다. 이러한 조건문이 많으면 이해가 어렵다.

해결 방법: 각 상태(ex. ON, OFF)를 캡슐화하고, State라는 인터페이스를 만들어서 구현한다. Light는 State와 집합 관계를 가진다.

각 상태와 이 상태에 의존적인 행위를 하나의 클래스로 캡슐화한다.
-> OCP에 위배되지 않고, 조건문을 사용하지 않아 코드의 이해가 쉬워진다!

interface State{
	public void on_button_pushed(Light light);
	public void off_button_pushed(Light light);
}

class ON implements State{
	public void on_button_pushed(Light light) {
		System.out.println("반응 없음");
	}
	public void off_button_pushed(Light light) {
		System.out.println("Light Off!");
		light.setState(new OFF());
	}
}

class OFF implements State{
	public void on_button_pushed(Light light) {
		System.out.println("Light ON!");
		light.setState(new ON());
	}
	public void off_button_pushed(Light light) {
		System.out.println("반응 없음");
	}
}


class Light{
	private State state;
	
	public Light() {
		state=new OFF();
	}
	
	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 Client{
	public static void main(String[] args) {
		Light light=new Light();
		light.off_button_pushed();
		light.on_button_pushed();
		light.off_button_pushed();
	}
}

그런데 ON/OFF 객체를 계속해서 만들 필요가 없다!
-> 싱글톤 패턴으로 변경한다.

class OFF implements State{
	private static OFF off=new OFF();
	private OFF() {}
	
	public static OFF getInstance() {
		return off;
	}
	
	public void on_button_pushed(Light light) {
		System.out.println("Light ON!");
		light.setState(ON.getInstance());
	}
	public void off_button_pushed(Light light) {
		System.out.println("반응 없음");
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *