문제 정의
문방구 앞에 있던 gumball 기계
처음 시작하면 quarter가 없고 사람이 quarter를 넣어주면 Has Quarter 상태가 된다.
만약, 여기서 반환 버튼을 누르면 다시 No Quarter 상태로 돌아간다.
Has Quarter에서 외부 이벤트가 발생하면(tums crank) Gumball Sold상태로 변경된다.
앞에 나온 state를 unique한 값으로 매핑하고 SOLD_OUT 상태부터 시작한다.
이벤트 함수인 insertQuarter(), ejectQuarter()에서는 현재 상태에 따라 다르게 반응해야하기 때문에
함수 내부에 분기문을 작성한다.
5개의 Gumball을 넣어주고 실행한다.
Gumball 기계가 생각보다 수익성이 나지 않아
1/10 확률로 2개의 Gumball이 나올 수 있도록 변경하고 싶다.
이를 위해 위 4가지 state 말고 다른 state를 넣고 싶다.
새로운 state를 넣기 위해서는 위 코드에서 많은 부분을 수정해야 한다.
문제 해결
위 코드에서 분기문을 제거하고, 대신 state별로 class를 만들어 state object에 delegate한다.
(변하는 부분과 변하지 않는 부분을 분리하여 변하는 부분은 외부에 delegate하는 방식으로 설계해야 한다.)
state interface를 정의해서 gumball 기계에서 일어날 수 있는 method를 넣는다.
state class에서는 각 state에서 실행되어야하는 부분을 구현한다.
event 함수가 실행될 때 각 state class에 delegate해주고 있다.
이 코드에서 새로운 state를 추가한다하면 state class만 추가하면 되기 때문에 손쉽게 확장할 수 있다. (OCP 만족)
State Pattern
객체의 behavior에 internal state따라 다른 반응을 보여야할 때 사용하는 패턴
(behavior가 state에 dependency를 가지고 있을 때)
Strategy 패턴과 차이
두 패턴 모두 delegate, composition을 활용했기 때문에 class만 보면 차이는 없고 intent 차이만 있다.
state는 state dependent behavior을 encapsulate하고(분기문을 줄여줌),
strategy는 알고리즘을 encapsulate한다(subclass을 줄여줌).
설계 이슈
누가 state 변화를 정의할 것인가?
1. context class : 간단한 상황이면 가능
2. concreteState class : 위 gumball 예시처럼 state별로 class 생성
concreteState object를 언제 생성하냐?
1. 필요할 때 런타임 중간에 동적으로 생성
2. gumball 처럼 처음에 모든 state object 생성
'💻 개발IT > Design Patterns' 카테고리의 다른 글
4. Creational 패턴 - Builder Pattern (0) | 2022.03.03 |
---|---|
4. Creational 패턴 - Abstract Factory Method Pattern (0) | 2022.03.02 |
4. Creational 패턴 - Factory Method Pattern (0) | 2022.03.02 |
3. Behavior 패턴 - Mediator Pattern (0) | 2022.03.01 |
3. Behavior 패턴 - Iterator Pattern (0) | 2022.02.28 |
3. Behavior 패턴 - Template Method Pattern (0) | 2022.02.28 |
3. Behavior 패턴 - Observer Pattern (0) | 2022.02.27 |
3. Behavior 패턴 - Strategy Pattern (0) | 2022.02.27 |