Personal-Study/Design Patterns
[TS Design Patterns] 행동 패턴 - 상태
Aaron-Kim
2023. 11. 12. 12:21
State
- 객체의 내부 상태가 변경될 때 해당 객체가 그의 행동을 변경할 수 있도록 함
- 객체가 행동을 변경할 때 객체가 클래스를 변경한 것처럼 보일 수 있음
- 상태 관련 행동들을 별도의 상태 클래스들로 추출하여 원래 객체가 자체적으로 작동하는 대신
상태 클래스들에 작업을 위임하도록 강제함
- TS에서 대규모 switch 기반 상태 머신들을 객체들로 변환하는데 사용
- 예시
/**
* The Context defines the interface of interest to clients. It also maintains a
* reference to an instance of a State subclass, which represents the current
* state of the Context.
*/
class Context {
/**
* @type {State} A reference to the current state of the Context.
*/
//@ts-ignore
private state: State;
constructor(state: State) {
this.transitionTo(state);
}
/**
* The Context allows changing the State object at runtime.
*/
public transitionTo(state: State): void {
console.log(`Context: Transition to ${(<any>state).constructor.name}.`);
this.state = state;
this.state.setContext(this);
}
/**
* The Context delegates part of its behavior to the current State object.
*/
public request1(): void {
this.state.handle1();
}
public request2(): void {
this.state.handle2();
}
}
/**
* The base State class declares methods that all Concrete State should
* implement and also provides a backreference to the Context object, associated
* with the State. This backreference can be used by States to transition the
* Context to another State.
*/
abstract class State {
//@ts-ignore
protected context: Context;
public setContext(context: Context) {
this.context = context;
}
public abstract handle1(): void;
public abstract handle2(): void;
}
/**
* Concrete States implement various behaviors, associated with a state of the
* Context.
*/
class ConcreteStateA extends State {
public handle1(): void {
console.log('ConcreteStateA handles request1.');
console.log('ConcreteStateA wants to change the state of the context.');
this.context.transitionTo(new ConcreteStateB());
}
public handle2(): void {
console.log('ConcreteStateA handles request2.');
}
}
class ConcreteStateB extends State {
public handle1(): void {
console.log('ConcreteStateB handles request1.');
}
public handle2(): void {
console.log('ConcreteStateB handles request2.');
console.log('ConcreteStateB wants to change the state of the context.');
this.context.transitionTo(new ConcreteStateA());
}
}
/**
* The client code.
*/
const context = new Context(new ConcreteStateA());
context.request1();
context.request2();
- 활용
반응형