-
[Design Pattern] State PatternLearn/Architecture 2022. 8. 29. 00:26
# 개요
- 객체가 내부적인 상태(state)에 따라 다르게 행동해야 할 때 사용하는 패턴
- UML의 state machine diagram을 구현할 때 가장 적합한 패턴
state에 따라 다르게 행동하도록 구현하는 가장 단순한 방법은 conditional statement를 쓰는 것이다.
public class GumballMachine { final static int SOLD_OUT = 0; final static int NO_QUARTER = 1; final static int HAS_QUARTER = 2; final static int SOLD = 3; int state = SOLD_OUT; int count = 0; public GumballMachine(int count) { this.count = count; if (count > 0) state = NO_QUARTER; } public void insertQuarter() { if (state == HAS_QUARTER) { .. } public void ejectQuarter() { if (state == HAS_QUARTER) { ..그러나 변경에 자유롭지 못하므로 좋은 방식이 아니다.
# State Pattern
해결하기 위한 아이디어는,
State Interface를 만들고 하위 클래스에서 action을 만들 수 있게 위임하는 것이다.

위 구조와 같이 Sold/SoldOut/NoQuarter/HasQuarter 각각의 상태에 따라 하위 클래스에서 구현한다.
예시로 아래의 insertQuater과 같이 state를 변화시키는 함수에서 set함수로 State를 바꿔준다.
public class NoQuarterState implements State { GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println("You inserted a quarter"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } ... }이와 같이 구성하면 OCP를 지킬 수 있다.
일반화해서 표현하면 다음과 같다.

State Pattern을 쓰면 State가 바뀔 때 마다 Behavior을 할 수 있다.
# State vs. Strategy
- 클래스 다이어그램 상으로는 차이가 없다.
- 어떤 문제를 해결하려 했는지(의도)가 다르다.
- State Pattern은 State에 dependency가 있는 behavior을 encapsulation하기 위해 사용
- 안쓰면 conditional statement가 많이 생김
- Strategy Pattern은 알고리즘을 encapsulation하기 위해 사용하고 상황에 따라 알고리즘이 바뀜
- state pattern에 비해서는 바뀌는 빈도가 적음
# Issue
누가 state의 변경을 정의할 것인가?
- 변경이 빈번하지 않고 단순할때는 Context Class를 만든다.
- 그렇지 않으면 ConcreteState 클래스에서 정의해주고 getter 함수를 제공한다.
Concrete object는 언제 만들 것인가?
- 필요할때마다 만든다.
- 종류가 많지 않으면 처음에 만들어놔도 된다.
'Learn > Architecture' 카테고리의 다른 글
[Design Pattern] Factory Method & Abstract Factory Patterns (0) 2022.08.29 [Design Pattern] Mediator Pattern (0) 2022.08.29 [Design Pattern] Iteration Pattern (0) 2022.08.28 [Design Pattern] Template Method Pattern (0) 2022.08.28 [Design Pattern] Observer Pattern (0) 2022.08.27