도찐개찐

[코드디자인패턴-JAVA] State Pattern 본문

프로그래밍/코드디자인패턴

[코드디자인패턴-JAVA] State Pattern

도개진 2024. 2. 29. 09:26

State Pattern

사용시점

  1. 객체의 행동이 상태에 따라 달라질 때: 객체가 특정 상태에 있을 때만 특정 행동을 해야 하거나, 상태에 따라 동일한 연산이 다르게 동작해야 하는 경우 유용합니다.
  2. 코드 중복을 피하고 싶을 때: 상태 패턴을 사용하면 상태를 각각의 클래스로 캡슐화할 수 있으므로, 각 상태에 따른 행동을 재상용 할 수 있고 코드 중복을 줄일 수 있습니다.
  3. 상태 전이 로직을 간결하게 만들고 싶을 때: 상태 패턴을 사용하면 상태와 행동을 각각의 클래스로 분리할 수 있으므로, 상태 전이 로직을 더 간결하고 유지 관리하기 쉽게 만들 수 있습니ㅏㄷ.

종류

  • State Pattern 자체는 특정한 "종류"로 분류 되지 않으며, 대신 상황과 요구 사항에 따라 구현됩니다.
  • 상태 패턴의 구현은 다음과 같은 두가지 주요 구성 요소로 나뉩니다.
  1. Context 클래스: 현재 상태를 포함해 외부에서의 요청을 해당 상태의 메서드로 위임합니다. 상태 변경이 필요한경우, Context는 새로운 상태로 전이 됩니다.
  2. State 인터페이스/추상 클래스와 ConcreteState: State 인터페이스는 특정 상태에서 수행할 수 있는 모든 행동을 선언하며, ConcreteState 클래스들은 이러한 행동을 구현합니다. 상태 전이는 ConcreteState 클래스들 사이에서 발생 합니다.

특징

  • 시스템이 상태에 따라 다르게 동작해야 할 때 객체 지향적인 방법으로 이를 구현
  • 코드의 유연성과 재사용성을 향상
  • 상태와 관련 된 로직의 대한 가독성 향상 및 관리 용이

1. Context Class,

  • State Interface : 모든 상태가 공유할 메서드를 선언합니다.
  • 각 상태의 특정 동작을 구현합니다. 각 상태에서 다음 상태로의 전환도 여기에서 처리합니다.
public class Context {}
public interface State {
    void handle(Context context);
}

public class Context {
    private State state;

    public Context(State state) {
        this.state = state;
    }

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

    public void request() {
        state.handle(this);
    }
}

2. ConcreteState Classes: 현재 상태를 추적하고 상태 객체에게 동작을 위임합니다.

public class RedState implements State { public void handle(Context context) {} }
public class GreenState implements State { public void handle(Context context) {} }
public class YellowState implements State { public void handle(Context context) {} }
public class RedState implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Red Light. Stop!");
        context.setState(new GreenState());
    }
}

public class GreenState implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Green Light. Go!");
        context.setState(new YellowState());
    }
}

public class YellowState implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Yellow Light. Prepare to Stop!");
        context.setState(new RedState());
    }
}
public class Main {
    public static void main(String[] args) {
        Context context = new Context(new RedState());
        context.request();
        context.request();
        System.out.println("-----------------------");
        context.request();
    }
}
Main.main(null)
Red Light. Stop!
Green Light. Go!
-----------------------
Yellow Light. Prepare to Stop!
장점:
  1. 상태와 행동의 캡슐화: 각 상태와 그 상태에 해당 하는 행동이 캡슐화 되 있어, 유지보수와 확장이 쉽습니다.
  2. 코드 중복 최소화: 상태별 생동이 각 상태 클래스에 정의 되어 있으므로 중복을 줄일 수 있습니다.
  3. 상태 전환 로직의 간결화: 상태 전환 로직이 각 상태 클래스 내에 캡슐화 되어 있으므로 전환 로직이 중앙화 되지 않고 분산 되어 있습니다.
단점:
  1. 클래스 수 증가: 상태별 클래스가 필요하므로 클래스의 수 증가
  2. 초기 설계 복잡성: 패턴을 처음 설정시 복잡도가 증가 할 수 있으며, 상태 전이가 많아지면 복잡성이 증가할 수 있습니다.
728x90
Comments