PHP PHP에서 상태 패턴(State Pattern) 활용 예시
페이지 정보

영삼이
본문
✅ PHP에서 상태 패턴(State Pattern) 활용 예시
상태 패턴은 객체의 내부 상태에 따라 행동을 바꾸는 디자인 패턴입니다. 조건문 없이 상태별 클래스를 분리해 유지보수성과 확장성을 높일 수 있습니다. 워크플로우, 주문 상태, 게시글 상태 등 다양한 실무 시나리오에 적합합니다.
🎯 문제 상황 예시
[code=php]
class Order {
private string $status = 'new';
public function next() {
if ($this->status === 'new') {
$this->status = 'paid';
} elseif ($this->status === 'paid') {
$this->status = 'shipped';
} elseif ($this->status === 'shipped') {
$this->status = 'delivered';
}
}
}
[/code]
-
조건문이 늘어나며 유지보수 어려움
-
새로운 상태 추가 시 if-else 지옥
✅ 상태 패턴 구조로 개선
1. 상태 인터페이스 정의
[code=php]
interface OrderState {
public function next(OrderContext $order): void;
public function getName(): string;
}
[/code]
2. 상태별 클래스 정의
[code=php]
class NewOrder implements OrderState {
public function next(OrderContext $order): void {
$order->setState(new PaidOrder());
}
public function getName(): string {
return '신규 주문';
}
}
class PaidOrder implements OrderState {
public function next(OrderContext $order): void {
$order->setState(new ShippedOrder());
}
public function getName(): string {
return '결제 완료';
}
}
class ShippedOrder implements OrderState {
public function next(OrderContext $order): void {
$order->setState(new DeliveredOrder());
}
public function getName(): string {
return '배송 중';
}
}
class DeliveredOrder implements OrderState {
public function next(OrderContext $order): void {
// 마지막 상태
}
public function getName(): string {
return '배송 완료';
}
}
[/code]
3. 컨텍스트 클래스
[code=php]
class OrderContext {
private OrderState $state;
public function __construct() {
$this->state = new NewOrder();
}
public function setState(OrderState $state): void {
$this->state = $state;
}
public function next(): void {
$this->state->next($this);
}
public function getStatus(): string {
return $this->state->getName();
}
}
[/code]
🚀 사용 예시
[code=php]
$order = new OrderContext();
echo $order->getStatus(); // 신규 주문
$order->next();
echo $order->getStatus(); // 결제 완료
$order->next();
echo $order->getStatus(); // 배송 중
[/code]
✅ 장점
항목 | 상태 패턴 | 조건문 방식 |
---|---|---|
확장성 | ✅ 좋음 | ❌ 나쁨 |
책임 분리 | ✅ 상태 클래스 별도 관리 | ❌ 로직 집중됨 |
테스트 용이성 | ✅ 상태 단위 테스트 가능 | ❌ 상태 분리 불가능 |
🧠 요약
-
상태 패턴은 조건문 없이 상태 전이를 관리할 수 있는 객체지향 설계
-
주문, 결제, 게시글 등 상태 기반 로직에서 매우 유용
-
각 상태를 클래스로 분리해 유연한 확장 구조 구현 가능
✅ PHP 프로젝트에서 이벤트 기반 아키텍처 적용하기
이벤트 기반 아키텍처는 코드의 결합도를 낮추고, 확장성과 유지보수성을 극대화하는 구조입니다. PHP에서도 Symfony EventDispatcher 같은 도구 없이 순수하게 이벤트 시스템을 구현할 수 있습니다.
📦 기본 개념
-
이벤트(Event): 어떤 일이 발생했음을 표현하는 객체
-
리스너(Listener): 이벤트에 반응하는 실행 코드
-
디스패처(Dispatcher): 이벤트를 발생시키고, 등록된 리스너에게 알림
🧱 이벤트 객체 정의
[code=php]
class UserRegisteredEvent {
public function __construct(public string $email) {}
}
[/code]
🔔 리스너 클래스 정의
[code=php]
class SendWelcomeEmail {
public function handle(UserRegisteredEvent $event): void {
echo "환영 이메일 전송: {$event->email}\n";
}
}
class LogUserRegistration {
public function handle(UserRegisteredEvent $event): void {
echo "사용자 등록 로그 기록: {$event->email}\n";
}
}
[/code]
🧰 간단한 디스패처 구현
[code=php]
class EventDispatcher {
private array $listeners = [];
public function listen(string $event, callable $listener): void {
$this->listeners[$event][] = $listener;
}
public function dispatch(object $event): void {
$eventClass = get_class($event);
foreach ($this->listeners[$eventClass] ?? [] as $listener) {
$listener($event);
}
}
}
[/code]
🚀 이벤트 등록 및 실행
[code=php]
$dispatcher = new EventDispatcher();
$dispatcher->listen(UserRegisteredEvent::class, [new SendWelcomeEmail(), 'handle']);
$dispatcher->listen(UserRegisteredEvent::class, [new LogUserRegistration(), 'handle']);
$dispatcher->dispatch(new UserRegisteredEvent('kim@example.com'));
[/code]
✅ 장점
-
리스너는 이벤트에만 반응, 호출자는 리스너 존재를 몰라도 됨
-
새로운 기능 추가 시 기존 코드 변경 없이 리스너만 추가
-
테스트와 디커플링에 매우 유리
🧠 요약
-
이벤트 기반 아키텍처는 확장성과 유지보수성을 극대화
-
PHP에서도 간단한 디스패처로 적용 가능
-
실무에서는 회원가입, 주문 처리, 알림 전송 등에 자주 사용
- 이전글PHP + Docker 환경 최적화 꿀팁 25.03.28
- 다음글실무에서 PHP Trait 남용을 피하는 방법 25.03.28
댓글목록
등록된 댓글이 없습니다.