전략 패턴
Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 70개 중 55번째.
전략 패턴(Strategy pattern)은 일련의 알고리즘 군을 정의하고, 각 알고리즘을 개별 클래스에 캡슐화하여 런타임에 이들을 서로 교체할 수 있게 하는 행동 패턴입니다. 동작을 직접 하드코딩하는 대신, 원하는 전략을 객체에 주입합니다.
이 패턴은 세 부분으로 구성됩니다: 알고리즘 계약을 정의하는 전략 인터페이스, 서로 다른 동작을 구현하는 구체적인 전략 클래스들, 그리고 전략을 사용하는 컨텍스트 클래스입니다:
public interface IPaymentStrategy
{
void Pay(decimal amount);
}
public class CreditCardPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via Credit Card");
}
public class PayPalPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via PayPal");
}
public class ShoppingCart
{
private IPaymentStrategy _paymentStrategy;
public void SetPaymentMethod(IPaymentStrategy strategy)
{
_paymentStrategy = strategy;
}
public void Checkout(decimal total)
{
_paymentStrategy.Pay(total);
}
}컨텍스트(ShoppingCart)는 어떤 결제 수단을 사용하고 있는지 알지 못합니다. 그저 제공된 전략에 대해 Pay()를 호출할 뿐입니다:
var cart = new ShoppingCart();
cart.SetPaymentMethod(new CreditCardPayment());
cart.Checkout(99.99m); // 신용카드로 99.99 결제됨
cart.SetPaymentMethod(new PayPalPayment());
cart.Checkout(49.99m); // PayPal로 49.99 결제됨전략 패턴(Strategy pattern)은 복잡한 조건부 로직을 제거합니다. 새로운 결제 수단을 추가한다는 것은 IPaymentStrategy를 구현하는 새로운 클래스를 생성하는 것을 의미하며, ShoppingCart에는 아무런 변경이 필요하지 않습니다. 이는 여러분의 코드를 확장에는 열려 있고 수정에는 닫혀 있게 만듭니다.
챌린지
쉬움전략(Strategy) 패턴을 사용하여 배송비 계산기를 만들어 보겠습니다. 배송 방법마다 서로 다른 가격 책정 알고리즘이 있으며, 시스템은 핵심 주문 처리 로직을 변경하지 않고도 런타임에 배송 방법을 전환할 수 있어야 합니다.
코드는 다음 세 개의 파일로 구성됩니다:
ShippingStrategy.cs:Shipping네임스페이스 내에double을 반환하는CalculateCost(double weight)메서드를 가진IShippingStrategy인터페이스를 정의합니다. 그런 다음 세 개의 구체적인 전략 클래스를 생성합니다:StandardShipping- 비용을weight * 1.5로 계산합니다.ExpressShipping- 비용을weight * 3.0 + 5.0으로 계산합니다 (고정 특송 요금 포함).OvernightShipping- 비용을weight * 5.0 + 10.0으로 계산합니다 (기본 요금이 더 높은 프리미엄 서비스).
OrderProcessor.cs: 동일한 네임스페이스에OrderProcessor클래스를 생성합니다. 이 클래스는 배송 전략을 사용하는 컨텍스트 클래스입니다. 다음을 포함해야 합니다:- 현재
IShippingStrategy를 보유할 프라이빗 필드 - 배송 전략을 변경하는
SetShippingMethod(IShippingStrategy strategy)메서드 - 현재 전략을 사용하여 배송비를 계산하고 반환하는
ProcessOrder(double weight)메서드
- 현재
Program.cs:OrderProcessor를 생성하고 런타임에 배송 전략을 교체하는 방법을 시연하여 모든 요소를 하나로 묶습니다. 동일한 프로세서가 전략을 변경하는 것만으로 서로 다른 알고리즘을 사용하여 비용을 계산할 수 있습니다.
두 개의 입력을 받게 됩니다:
- 배송 방법 유형:
standard,express, 또는overnight - 소수점 숫자로 된 패키지 무게 (예:
4.5)
OrderProcessor를 생성하고, 입력 유형에 따라 적절한 배송 전략을 설정한 다음, 주문을 처리하고 계산된 비용을 출력하세요.
예를 들어, 입력이 express와 4.5인 경우 출력은 다음과 같아야 합니다:
18.5이것은 전략 패턴의 강력함을 보여줍니다. OrderProcessor 자체에는 배송 계산 로직이 포함되어 있지 않습니다. 단순히 주어진 전략에 위임할 뿐이므로, 프로세서를 전혀 수정하지 않고도 새로운 배송 방법(예: DroneDelivery)을 쉽게 추가할 수 있습니다!
치트 시트
전략 패턴(Strategy pattern)은 알고리즘 군을 정의하고 각각을 별도의 클래스에 캡슐화하여 실행 중에 서로 교체 가능하게 만드는 행동 패턴입니다.
이 패턴은 세 부분으로 구성됩니다:
- 전략 인터페이스(Strategy interface): 알고리즘 규약을 정의합니다
- 구체적인 전략 클래스(Concrete strategy classes): 다양한 동작을 구현합니다
- 컨텍스트 클래스(Context class): 구현 세부 사항을 알지 못한 채 전략을 사용합니다
예제 구조:
// 전략 인터페이스
public interface IPaymentStrategy
{
void Pay(decimal amount);
}
// 구체적인 전략들
public class CreditCardPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via Credit Card");
}
public class PayPalPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via PayPal");
}
// 컨텍스트 클래스
public class ShoppingCart
{
private IPaymentStrategy _paymentStrategy;
public void SetPaymentMethod(IPaymentStrategy strategy)
{
_paymentStrategy = strategy;
}
public void Checkout(decimal total)
{
_paymentStrategy.Pay(total);
}
}사용법 - 런타임에 전략 교체하기:
var cart = new ShoppingCart();
cart.SetPaymentMethod(new CreditCardPayment());
cart.Checkout(99.99m); // Credit Card를 통해 99.99 결제됨
cart.SetPaymentMethod(new PayPalPayment());
cart.Checkout(49.99m); // PayPal을 통해 49.99 결제됨장점:
- 복잡한 조건부 로직을 제거합니다
- 확장에는 열려 있고 수정에는 닫혀 있습니다
- 새로운 전략을 추가할 때 기존 코드를 변경하지 않고 새로운 클래스만 생성하면 됩니다
직접 해보기
using System;
using Shipping;
class Program
{
public static void Main(string[] args)
{
// 입력 읽기
string shippingType = Console.ReadLine();
double weight = Convert.ToDouble(Console.ReadLine());
// TODO: OrderProcessor 인스턴스 생성
// TODO: shippingType ("standard", "express", 또는 "overnight")에 따라,
// 적절한 배송 전략을 생성하고 processor에 설정
// TODO: 주문을 처리하고 계산된 비용을 출력
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.