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!

댓글남기기