상태란 객체가 시스템에 존재하는 동안, 즉 객체의 라이프 타임 동안 객체가 가질 수 있는 어떤 조건이나 상황을 표현한다.
스테이트 패턴
스테이트 패턴은 상태에 따라 동일한 작업이 다른 방식으로 실행될 때 해당 상태가 작업을 수행하도록 위임하는 디자인 패턴이다.
스테이트 패턴의 목표는 현재 시스템이 어떤 상태에 있는지와 상관없이 구성하고, 상태변화에도 독립적이도록 코드를 구현하는 것이다. 이를 위해서 상태를 클래스로 분리해 캡슐화 한다.
Light(형광등)은 State를 attribute로 가지고 있으며, 외부에서 의존성을 주입 받기 위해 setState Method까지 가지고 있다. State Interface를 구현한 형광등의 상태인 ON, OFF가 있으며, 각 상태에서 on, off를 실행하는 코드를 작성해준다.
public interface State {
public void on_button_pushed(Light light);
public void off_button_pushed(Light light);
}
public class ON implements State {
@Override
public void on_button_pushed(Light light) {
System.out.println("반응 없음"); // 켜진상태에서는 on을 눌러도 아무 행동이 일어나면 안되겠지.
}
@Override
public void off_button_pushed(Light light) {
System.out.println("Light Off");
light.setState(new OFF());
}
}
public class OFF implements State {
@Override
public void on_button_pushed(Light light) {
System.out.println("Light Off");
light.setState(new ON());
}
@Override
public void off_button_pushed(Light light) {
System.out.println("반응 없음");
}
}
Light코드만 봐도 어떤 행동을 하는지 쉽게 알 수 있고, 각 상태에 대한 처리를 상태 클래스에서 처리하기 때문에 훨씬 간단하게 코딩할 수 있다. 실제로 작성해보니 진짜 편한걸 알겠다..ㄷ.ㄷ 상태가 새로운 상태로 교체되어도 Light클래스는 전혀 영향을 받지 않는 것을 확인할 수 있다.
public class Light {
private State state;
public Light() {
state = new OFF();
}
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);
}
}
스테이트 패턴 설명
- State : 시스템의 모든 상태에 공통의 인터페이스를 제공한다. 따라서 이 인터페이스를 실체화한 어떤 상태 클래스도 기존 상태 클래스를 대신해 교체해서 사용할 수 있다.
- State1, State2, State3 : Context 객체가 요청한 작업을 자신의 방식으로 실제 실행한다. 대부분의 경우 다음 상태를 결정해 상태 변경을 Context 객체에 요청하는 역할도 수행한다.
- Context : State를 이용하는 역할 수행. 현재 시스템의 상태를 나타내는 상태 변수와 실제 시스템의 상태를 구성하는 여러 변수가 있다. 그리고, 각 상태 클래스에서 상태 변경을 요청해 상태를 바꿀 수 있도록 하는 setState메서드가 제공된다. Context 요소를 구현한 클래스의 request메서드는 실제 행위를 실행하는 대신 해당 상태 객체에 행위 실행을 위임한다.
연습문제
1. 스테이트 패턴 vs 스트래티지 패턴
구조적인 면에서는 상당히 비슷하다. 스테이트 패턴은 상태를 캡슐화한 것이고, 스트래티지 패턴은 전략을 캡슐화한 것이다. ...?
2. 선풍기의 상태 머신 다이어그램
3. 코드 7-5 참고, 취침등 상태를 추가한 Light 클래스 완성. --> Light클래스는 손대지 않고, SLEEPING state만 추가하면 된다.. 오우.. 엄청나..
5. 벤딩머신을 스테이트 패턴을 활용해 작성.
연습문제의 해설과 가장큰 차이점은 VendingMachine에서 Drinking 객체와 MoneyBox 객체를 따로 설계하고, 이를 Attribute으로 사용한다는 점이다. 나는 음료 가격과 재고, 투여된 금액을 String, int형으로 저장을 했었다.
https://github.com/dhdnjswnd/JavaObjectiveDesignPattern/tree/main/src/chapter7_statepattern
공부하는 책
'Java > Java 객체지향 디자인 패턴' 카테고리의 다른 글
[Java 객체 지향 디자인 패턴] 9. 옵서버 패턴 - 통보의 캡슐화 (0) | 2022.05.09 |
---|---|
[Java 객체 지향 디자인 패턴] 8. 커맨드 패턴 - Command Pattern : 기능의 캡슐화 (0) | 2022.03.17 |
[Java 객체 지향 디자인 패턴] 6. 싱글턴 패턴 - Singleton Pattern : 단하나! 비동기 시 주의 (0) | 2022.02.23 |
[Java 객체 지향 디자인 패턴] 5. 스트래티지 패턴 - Strategy Pattern~! 전략 패턴~! (0) | 2022.02.23 |
[Java 객체 지향 디자인 패턴] 4. 디자인 패턴 - 바퀴를 다시 발명하지 말라~! (0) | 2022.02.16 |
댓글