ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [디자인 패턴] 전략 패턴 (Strategy Pattern)
    Design Patterns 2025. 1. 28. 22:49

    전략 패턴이란?

    • 기능을 캡슐화하여 동적으로 기능을 선택할 수 있게 해주는 디자인 패턴이다.
    • 비슷한 작업을 수행하는 여러 기능이 있을 때, 이 기능들을 개별 클래스로 캡슐화하고, 실행 시점에 필요한 기능을 선택할 수 있도록 한다.

     핵심 개념

    • 캡슐화: 각 기능을 별도의 클래스로 분리
    • 유연성: 실행 시점에 행위를 선택, 변경 가능
    • 구성(Composition): 실행 클래스가 특정 기능을 직접 구현하지 않고, 해당 기능을 다른 클래스에서 위임 받아 실행

     구조

    • Context: 클라이언트가 사용하는 객체로 전략(기능)을 실행한다.
    • Strategy: 기능을 정의하는 인터페이스
    • ConcreteStrategy: Strategy를 구현하는 구체적인 기능 클래스

     장단점

    장점

    • 개방-폐쇄 원칙(OCP) 준수: 기능을 추가하거나 변경해도 기존 코드에 영향을 미치지 않음
    • 코드 재사용성 증가: 기능을 독립적인 클래스로 분리
    • 유연성: 실행 시점에 전략을 쉽게 변경 가능

    단점

    • 구현 복잡성 증가: 간단한 작업에도 많은 클래스를 생성
    • 추가 비용 발생: 객체를 생성하고 관리해야 하므로 약간의 성능 비용

     예제 코드: 여러가지 결제 방식

    • 결제 애플리케이션을 만든다고 가정
    • 여러가지 결제 방식 중 하나를 결제 시점에 선택할 수 있어야 함

    1️⃣ Strategy 인터페이스 정의

    public interface PaymentStrategy {
        void pay(int amount);
    }

    2️⃣ ConcreteStrategy 클래스 구현

    // 신용카드
    @RequiredArgsConstructor
    public class CreditCardPayment implements PaymentStrategy {
    
        private final String cardNumber;
    
        @Override
        public void pay(int amount) {
            System.out.println(amount + "원을 신용카드(" + cardNumber + ")로 결제합니다.");
        }
    }
    
    // 페이팔
    @RequiredArgsConstructor
    public class PayPalPayment implements PaymentStrategy {
    
        private final String email;
    
        @Override
        public void pay(int amount) {
            System.out.println(amount + "원을 PayPal 계정(" + email + ")으로 결제합니다.");
        }
    }
    
    // 비트코인
    @RequiredArgsConstructor
    public class BitcoinPayment implements PaymentStrategy {
    
        private final String walletId;
    
        @Override
        public void pay(int amount) {
            System.out.println(amount + "원을 비트코인 지갑(" + walletId + ")으로 결제합니다.");
        }
    }
    

    3️⃣ Context 클래스 정의

    // 전략을 실제로 실행하는 context 클래스
    @RequiredArgsConstructor
    public class PaymentContext {
    
        private final PaymentStrategy strategy;
    
        // 결제 수행
        public void pay(int amount) {
            strategy.pay(amount);
        }
    }

    4️⃣ 사용 예시 및 결과

    public class AppMain {
        public static void main(String[] args) {
            CreditCardPayment creditCardPayment = new CreditCardPayment("1234-5678-9012-3456");
            PaymentContext context1 = new PaymentContext(creditCardPayment);
            context1.pay(10000);
    
            PayPalPayment payPalPayment = new PayPalPayment("user@example.com");
            PaymentContext context2 = new PaymentContext(payPalPayment);
            context2.pay(20000);
    
            BitcoinPayment bitcoinPayment = new BitcoinPayment("bitcoin id");
            PaymentContext context3 = new PaymentContext(bitcoinPayment);
            context3.pay(30000);
        }
    }
    10000원을 신용카드(1234-5678-9012-3456)로 결제합니다.
    20000원을 PayPal 계정(user@example.com)으로 결제합니다.
    30000원을 비트코인 지갑(bitcoin id)으로 결제합니다.

     

    이처럼 전략 패턴을 사용하면 다양한 알고리즘을 독립적으로 관리하고, 실행 시점에 동적으로 사용할 수 있다. 특히 확장성과 유연성이 중요한 프로젝트에서 유용하게 사용된다.