Laravel에서 Resolver를 사용한 서비스 선택 간소화
Source: Dev.to
문제: 너무 많은 if‑else 조건
if ($paymentType === 'stripe') {
$service = new StripePaymentService();
} elseif ($paymentType === 'paypal') {
$service = new PaypalPaymentService();
} else {
throw new Exception('Invalid payment type');
}
$service->charge($data);
이 접근 방식의 문제점은?
- 비즈니스 로직이 구체적인 구현에 강하게 결합되어 있습니다.
- 새로운 결제 게이트웨이를 추가하려면 기존 코드를 수정해야 합니다.
- 테스트와 유지보수가 어렵습니다.
- 개방/폐쇄 원칙(Open/Closed Principle)을 위반합니다.
코드는 동작하지만 확장성이 떨어집니다.
Resolver란?
Resolver는 런타임 데이터에 따라 어떤 서비스 구현을 사용할지 결정하는 역할을 하는 클래스입니다. 간단히 말해, Resolver는 올바른 서비스 클래스를 반환해 주어 비즈니스 로직을 깔끔하게 유지합니다.
실제 예시: 결제 서비스 Resolver
Step 1: 공통 인터페이스 만들기
$this->stripePaymentService,
'paypal' => $this->paypalPaymentService,
default => throw new InvalidArgumentException('Unsupported payment type'),
};
}
}
왜 생성자 주입을 사용할까?
- 의존성을 명시적으로 드러내어 이해하기 쉬워집니다.
- 단위 테스트가 용이해집니다(서비스를 모킹할 수 있음).
- Resolver가 선택 로직에만 집중할 수 있습니다.
- Laravel의 의존성 주입 컨테이너를 활용합니다.
Note: Resolver 내부에서
app()을 사용해 서비스를 해결할 수도 있지만, 일반적으로 더 깔끔한 아키텍처와 테스트 용이성을 위해 생성자 주입이 선호됩니다.
Step 4: 비즈니스 로직에서 Resolver 사용하기
get('payment_type');
$service = $resolver->resolve($paymentType);
$service->charge($request->all());
return response()->json([
'message' => 'Payment processed successfully',
]);
}
}
✨ 깔끔하고 가독성이 좋으며 확장이 쉽습니다.
새로운 서비스를 추가하는 것이 쉬움
나중에 Razorpay를 추가하고 싶다면?
PaymentServiceInterface를 구현하는RazorpayPaymentService를 만든다.- Resolver에 아래와 같이 추가한다:
'razorpay' => $this->razorpayPaymentService,
컨트롤러나 다른 비즈니스 로직을 수정할 필요가 없습니다.
Resolver 사용의 장점
- 코드가 더 깔끔하고 가독성이 높아집니다.
- 새로운 서비스를 쉽게 추가할 수 있습니다.
- SOLID 원칙을 따릅니다.
- 서비스 선택 로직이 중앙 집중화됩니다.
- 단위 테스트가 간단합니다.
보너스: Resolver를 더 유연하게 만들기
Config‑Based Mapping
// config/payment.php
return [
'stripe' => StripePaymentService::class,
'paypal' => PaypalPaymentService::class,
];
Config를 활용한 Resolver
<?php
class PaymentServiceResolver
{
public function resolve(string $type): PaymentServiceInterface
{
$service = config("payment.$type");
if (! $service) {
throw new InvalidArgumentException('Unsupported payment type');
}
return app($service);
}
}
이 접근 방식은 시스템을 더욱 설정 가능하게 만들어 줍니다.
최종 생각
Resolver는 Laravel에서 여러 서비스 구현을 관리하기 위한 간단하면서도 강력한 패턴입니다. 이를 통해 다음을 달성할 수 있습니다.
- 복잡한 조건문을 피한다.
- 비즈니스 로직을 깔끔하게 유지한다.
- 시스템을 유연하고 확장 가능하게 만든다.
여러 API, 결제 게이트웨이, 혹은 제공자를 다루는 경우, Resolver를 활용하면 코드 품질을 크게 향상시킬 수 있습니다.