inblog logo
|
LifeLog, DevLog
    Tech

    전략 패턴

    KYJTHEYJ's avatar
    KYJTHEYJ
    Dec 12, 2025
    전략 패턴
    Contents
    전략 패턴예시수정된 예시예시 2수정된 예시 2

    전략 패턴

    로직을 캡슐화해서 런타임에 교체가 가능하도록 만드는 패턴

    • 상속을 사용하는 것이 아님

    • 런타임에 동작 변경이 가능

    예시

    public class PaymentService {
        public void pay(String paymentType, int amount) {
            if(paymentType.equals("CARD")) {
                System.out.println("신용카드로 " + amount + "원 결제");
                // 카드 결제 로직
                // ...
                
            } else if(paymentType.equals("CASH")) {
                System.out.println("현금으로 " + amount + "원 결제");
                // 현금 결제 로직
                // ...
                
            } else if(paymentType.equals("KAKAO")) {
                System.out.println("카카오페이로 " + amount + "원 결제");
                // 카카오페이 로직
                // ...
                
            } else if(paymentType.equals("TOSS")) {
                System.out.println("토스로 " + amount + "원 결제");
                // 토스 로직
                // ...
                
            } else if(paymentType.equals("NAVER")) {
                System.out.println("네이버페이로 " + amount + "원 결제");
                // 네이버페이 로직
                // ...
            }
        }
    }
    • 이런 상황은 if-else에 종속되어 런타임에 수단을 변경할 수가 없음

      무엇보다 SOLID 원칙 위반

    → OCP 위반, 클래스를 새로운 기능 추가시 추가가 아님

    수정된 예시

    // 신용카드 결제 전략
    public class CardPayment implements PaymentStrategy {
        private String cardNumber;
        
        public CardPayment(String cardNumber) {
            this.cardNumber = cardNumber;
        }
        
        @Override
        public void pay(int amount) {
            System.out.println("신용카드(" + cardNumber + ")로 " + amount + "원 결제");
            // 카드 결제 API 호출
        }
    }
    
    // 카카오페이 전략
    public class KakaoPayment implements PaymentStrategy {
        private String phoneNumber;
        
        public KakaoPayment(String phoneNumber) {
            this.phoneNumber = phoneNumber;
        }
        
        @Override
        public void pay(int amount) {
            System.out.println("카카오페이(" + phoneNumber + ")로 " + amount + "원 결제");
            // 카카오페이 API 호출
        }
    }
    
    // 토스 결제 전략
    public class TossPayment implements PaymentStrategy {
        private String accountNumber;
        
        public TossPayment(String accountNumber) {
            this.accountNumber = accountNumber;
        }
        
        @Override
        public void pay(int amount) {
            System.out.println("토스(" + accountNumber + ")로 " + amount + "원 결제");
            // 토스 API 호출
        }
    }
    
    // 현금 결제 전략
    public class CashPayment implements PaymentStrategy {
        @Override
        public void pay(int amount) {
            System.out.println("현금으로 " + amount + "원 결제");
            System.out.println("거스름돈을 확인하세요.");
        }
    }
    • OCP 만족, 각자의 전략 대로 클래스가 만들어짐

    // 수정된 Service 단
    public class PaymentService {
        private PaymentStrategy paymentStrategy;
        
        // 생성자로 전략 주입
        public PaymentService(PaymentStrategy paymentStrategy) {
            this.paymentStrategy = paymentStrategy;
        }
        
        // 런타임에 전략 변경 가능
        public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
            this.paymentStrategy = paymentStrategy;
        }
        
        // 전략 실행
        public void processPayment(int amount) {
            paymentStrategy.pay(amount);
        }
    }
    public class Main {
        public static void main(String[] args) {
            // 카드 결제
            PaymentService service = new PaymentService(
                new CardPayment("1234-5678-9012-3456")
            );
            service.processPayment(50000);
            // 출력: 신용카드(1234-5678-9012-3456)로 50000원 결제
            
            // 런타임에 카카오페이로 변경
            service.setPaymentStrategy(
                new KakaoPayment("010-1234-5678")
            );
            service.processPayment(30000);
            // 출력: 카카오페이(010-1234-5678)로 30000원 결제
            
            // 현금으로 변경
            service.setPaymentStrategy(new CashPayment());
            service.processPayment(10000);
            // 출력: 현금으로 10000원 결제
            //      거스름돈을 확인하세요.
        }
    }

    예시 2

    • 어떤 게임에서 챔피언을 부활 시키려는 하려하는 상황

      • 모든 챔피언마다 부활 방식을 if-else 로…?

      • 그럼 런타임에선 어떻게 할건데..?

    수정된 예시 2

    • 우선 부활 방식을 지정하도록 확장

    동일 클래스 내 부활 기능을 전략 패턴으로 확장1
    동일 클래스 내에서 부활이 실행되는 메서드, 이 메서드도 사용 중임
    동일 클래스 내 부활 기능을 전략 패턴으로 확장2, 일단 오버라이드 없으면 기본 부활로
    공용 부활 메서드, 사이온 지정 부활 메서드
    각각의 챔피언 클래스에서 부활 방식을 우선 지정, 사이온 클래스는 지정된 부활로 오버라이드
    이제 Main 실행부에서 setResurrection에서 메서드 지정하여 확장

    → 이 setResurrection은 추후에 실행 중에 재지정 하여 사용도 가능함

    Share article
    Contents
    전략 패턴예시수정된 예시예시 2수정된 예시 2

    LifeLog, DevLog - https://github.com/KYJTHEYJ

    RSS·Powered by Inblog