[GoF] State 패턴

패턴명칭

State

필요한 상황

상태에 따라 실행되는 기능이 달라질때 유연하게 대응할 수 있는 패턴이다.

예제 코드

7일간 하루 하루에 대한 일정을 주사위를 던져 짝수날에는 놀고 홀수날에는 공부를 하는 시스템이다. 여기서 상태는 주사위가 짝수인지 홀수인지이다. 다양한 상태를 동일한 인터페이스로 다룰 수 있도록 State 인터페이스를 두고 이 State를 PlayState와 StudyState가 구현한다. 각각은 상태에 따른 놀기와 공부하기이다. Schedule는 상태를 변경하는 클래스이다. 먼저 State 인터페이스는 다음과 같다.

package tstThread;

public interface State {
	void morning();
	void afternoon();
	void night();
}

다음은 공부하기 상태에 대한 StudyState 클래스이다.

package tstThread;

public class StudyState implements State {
	@Override
	public void morning() {
		System.out.println("I'm studying the math.");
	}

	@Override
	public void afternoon() {
		System.out.println("I'm studying the programming.");
	}

	@Override
	public void night() {
		System.out.println("I'm studying the physics.");
	}
}

다음은 놀기 상태에 대한 PlayState 클래스이다.

package tstThread;

public class PlayState implements State {

	@Override
	public void morning() {
		System.out.println("I am playing the piano.");
	}

	@Override
	public void afternoon() {
		System.out.println("I am playing the starcraft game.");
	}

	@Override
	public void night() {
		System.out.println("I am listening the pop song.");
	}
}

다음은 일주일에 대한 시간 흐름을 제어하고 주사위를 던저 상태를 변경하는 Schedule 클래스이다.

package tstThread;

public class Schedule {
	private State state;
	
	public void setState(State state) {
		this.state = state;
	}
	
	public void doInTheMorning() {
		if(state != null) {
			System.out.print("[Morning] ");
			state.morning();
		}
	}
	
	public void doInTheAfternoon() {
		if(state != null) {
			System.out.print("[Afternoon] ");
			state.afternoon();
		}
	}
	
	public void doInTheNight() {
		if(state != null) {
			System.out.print("[Night] ");
			state.night();
		}
	}
}

지금까지의 클래스를 실행하는 코드는 다음과 같다.

package tstThread;

import java.util.Random;

public class Main {
	private static Random dice = new Random();
	public static void main(String[] args) {
		Schedule schedule = new Schedule();
		
		String days[] = { "Sunday", "Monday", "Tuesday", "Thursday", "Friday", "Saturday" };
		for(int nDay=0; nDay<6; nDay++) {
			int nDice = dice.nextInt(7);
			
			if(nDice % 2 == 0) {
				schedule.setState(new PlayState());
			} else {
				schedule.setState(new StudyState());
			}
			
			System.out.println();
			System.out.println("# " + days[nDay]);
			schedule.doInTheMorning();
			schedule.doInTheAfternoon();
			schedule.doInTheNight();
		}
	}
}

실행결과는 다음과 같다.

# Sunday
[Morning] I am playing the piano.
[Afternoon] I am playing the starcraft game.
[Night] I am listening the pop song.

# Monday
[Morning] I am playing the piano.
[Afternoon] I am playing the starcraft game.
[Night] I am listening the pop song.

# Tuesday
[Morning] I am playing the piano.
[Afternoon] I am playing the starcraft game.
[Night] I am listening the pop song.

# Thursday
[Morning] I am playing the piano.
[Afternoon] I am playing the starcraft game.
[Night] I am listening the pop song.

# Friday
[Morning] I'm studying the math.
[Afternoon] I'm studying the programming.
[Night] I'm studying the physics.

# Saturday
[Morning] I'm studying the math.
[Afternoon] I'm studying the programming.
[Night] I'm studying the physics.
이 글은 소프트웨어 설계의 기반이 되는 GoF의 디자인패턴에 대한 강의자료입니다. 완전한 실습을 위해 이 글에서 소개하는 클래스 다이어그램과 예제 코드는 완전하게 실행되도록 제공되지만, 상대적으로 예제 코드와 관련된 설명이 함축적으로 제공되고 있습니다. 이 글에 대해 궁금한 점이 있으면 댓글을 통해 남겨주시기 바랍니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다