상태 패턴은 객체의 상태에 따라 행동을 변경하는 디자인 패턴입니다. 조건문으로 특정 상태를 변경하는 것이 아닌 상태를 객체화하여 필요에 따라 다르게 행동하도록 위임합니다.
State란 객체가 가질 수 있는 어떤 조건이나 상황을 나타냅니다.
예를 들어 자동차에 시동이 걸려있는 상태라면 속력을 올리거나 줄일 수 있습니다. 만약 자동차의 시동이 꺼지는 상태라면 속력을 올리거나 줄일 수 없습니다. 자동차 시동 상태에 따라 메소드가 달라집니다.

State 패턴을 이용하여 신호등을 구현하는 간단한 예시코드입니다.
TrafficLightContext.ts
현재 상태(TrafficLightState)를 유지하고, 상태 전환 요청(changeLight)을 처리합니다.
import { TrafficLightState } from "./TrafficLightState";
// Context 클래스: 현재 신호등 상태를 관리하는 클래스
export class TrafficLightContext {
private state: TrafficLightState;
constructor(state: TrafficLightState) {
this.state = state;
}
public setState(state: TrafficLightState): void {
this.state = state;
}
public renderCurrentTraffic() {
this.state.renderTraffic();
}
public changeState(): void {
this.state.changeLight(this);
}
}
TrafficLightState.ts
상태의 인터페이스로, 모든 구체적인 상태 클래스는 이 인터페이스를 구현합니다.
import { TrafficLightContext } from "./TrafficLightContext";
// State 인터페이스
export interface TrafficLightState {
changeLight(context: TrafficLightContext): void;
renderTraffic(): void;
}
RedLight.ts
changeLight 메서드를 통해 상태를 변경합니다.
renderTraffic 메서드를 통해 UI를 렌더링합니다.
빨간불 ⇒ 초록불로 상태를 변경합니다.
import { GreenLight } from "./GreenLight";
import { TrafficLightContext } from "./TrafficLightContext";
import { TrafficLightState } from "./TrafficLightState";
// ConcreteState 클래스 - 빨간불
export class RedLight implements TrafficLightState {
private static instance: RedLight;
public static getInstance(): RedLight {
if (!RedLight.instance) {
RedLight.instance = new RedLight();
}
return RedLight.instance;
}
public renderTraffic() {
const redTraffic = document.querySelector(".red")!;
const yellowTraffic = document.querySelector(".yellow")!;
const greenTraffic = document.querySelector(".green")!;
const message = document.querySelector(".message")!;
yellowTraffic.classList.remove("active");
greenTraffic.classList.remove("active");
redTraffic.classList.add("active");
message.textContent = "빨간불: 차량 정지!";
}
public changeLight(context: TrafficLightContext): void {
context.setState(GreenLight.getInstance());
}
}
YellowLight.ts
changeLight 메서드를 통해 상태를 변경합니다.
renderTraffic 메서드를 통해 UI를 렌더링합니다.
노란불 ⇒ 빨간불로 상태를 변경합니다.
import { RedLight } from './RedLight';
import { TrafficLightContext } from "./TrafficLightContext";
import { TrafficLightState } from "./TrafficLightState";
// ConcreteState 클래스 - 노란불
export class YellowLight implements TrafficLightState {
private static instance: YellowLight;
static getInstance(): YellowLight {
if (!YellowLight.instance) {
YellowLight.instance = new YellowLight();
}
return YellowLight.instance;
}
public renderTraffic() {
const redTraffic = document.querySelector(".red")!;
const yellowTraffic = document.querySelector(".yellow")!;
const greenTraffic = document.querySelector(".green")!;
const message = document.querySelector(".message")!;
redTraffic.classList.remove("active");
greenTraffic.classList.remove("active");
yellowTraffic.classList.add("active");
message.textContent = "노란불: 신호 변경 주의!";
}
public changeLight(context: TrafficLightContext): void {
context.setState(RedLight.getInstance());
}
}
GreenLight.ts
changeLight 메서드를 통해 상태를 변경합니다.
renderTraffic 메서드를 통해 UI를 렌더링합니다.
초록불 ⇒ 노란불로 상태를 변경합니다.
import { TrafficLightContext } from "./TrafficLightContext";
import { TrafficLightState } from "./TrafficLightState";
import { YellowLight } from "./YellowLight";
// ConcreteState 클래스 - 초록불
export class GreenLight implements TrafficLightState {
private static instance: GreenLight;
public static getInstance(): GreenLight {
if (!GreenLight.instance) {
GreenLight.instance = new GreenLight();
}
return GreenLight.instance;
}
public renderTraffic() {
const redTraffic = document.querySelector(".red")!;
const yellowTraffic = document.querySelector(".yellow")!;
const greenTraffic = document.querySelector(".green")!;
const message = document.querySelector(".message")!;
yellowTraffic.classList.remove("active");
redTraffic.classList.remove("active");
greenTraffic.classList.add("active");
message.textContent = "초록불: 차량 출발";
}
public changeLight(context: TrafficLightContext): void {
context.setState(YellowLight.getInstance());
}
}

changeState 메서드를 호출하여 상태를 변경하며, renderCurrentTraffic 메서드를 호출하여 상태에 따른 UI를 업데이트합니다.changeLight, renderTraffic 메서드를 정의하고, 구체적인 상태 클래스들(RedLight, YellowLight, GreenLight)이 이 메서드를 구현합니다.Context는 새로운 상태를 설정하고, 해당 상태의 renderTraffic 메서드를 호출하여 UI를 업데이트합니다.State 패턴은 객체의 상태에 따라 동작을 달리하는 디자인 패턴으로, 조건문 대신 상태를 객체로 캡슐화하여 관리합니다. 이를 통해 코드의 가독성과 유지보수성이 향상됩니다. 각 상태는 자신의 동작을 관리하며, 상태 전이는 명확하게 정의됩니다. 그러나 상태가 많아지면 클래스가 증가할 수 있어 복잡성이 커질 수 있습니다.