Design Pattern with Java

6. 전략 패턴(Strategy Pattern)

초코너무조코 2025. 1. 15. 12:19
728x90

 


목차

    전략 패턴(Strategy Pattern)란?

    전략 패턴(Strategy Pattern)은 행동 디자인 패턴 중 하나로, 알고리즘을 클래스로 캡슐화하여, 클라이언트에서 실행 시 적절한 알고리즘을 동적으로 변경할 수 있도록 돕는 패턴입니다. 즉, 어떤 작업을 수행하는 방법을 전략(Strategy)으로 분리하여, 이를 필요에 따라 유연하게 교체할 수 있도록 만드는 구조입니다.

    전략 패턴의 특징

    • 알고리즘을 클래스로 캡슐화하여, 알고리즘을 실행하는 클래스를 변경하지 않고, 전략을 바꿀 수 있습니다.
    • 알고리즘을 독립적으로 변경할 수 있어 유연성확장성을 제공합니다.
    • 여러 알고리즘을 인터페이스나 추상 클래스를 통해 정의하고, 이를 구체적인 전략 클래스에서 구현합니다.
    • 클라이언트는 실행 시점에서 알고리즘을 선택하고 적용할 수 있습니다.

    전략 패턴의 구성 요소

    전략 패턴은 다음과 같은 구성 요소로 이루어집니다:

    1. 컨텍스트(Context): 전략을 사용하는 객체입니다. 클라이언트는 이 객체를 통해 특정 전략을 설정하고 실행합니다.
    2. 전략(Strategy): 알고리즘을 정의하는 인터페이스 또는 추상 클래스입니다. 다양한 알고리즘은 이 전략 인터페이스를 구현하거나 확장하여 정의됩니다.
    3. 구체적인 전략(Concrete Strategy): 알고리즘을 실제로 구현하는 클래스들입니다. 각기 다른 알고리즘을 이 클래스들에서 구현하여 클라이언트가 필요에 맞는 알고리즘을 선택할 수 있게 합니다.

    전략 패턴 예시 (Java)

    이번에는 전략 패턴을 사용하여 가격 계산 방식을 다룬 예시를 만들어 보겠습니다. 예를 들어, 고객에게 할인을 적용하는 방식이 여러 가지일 수 있습니다. 이때 전략 패턴을 사용하여 할인 전략을 유연하게 변경할 수 있습니다.

    // 전략 인터페이스: 할인 방식 정의
    interface DiscountStrategy {
        double applyDiscount(double price);
    }
    
    // 구체적인 전략 1: 10% 할인
    class Discount10Percent implements DiscountStrategy {
        @Override
        public double applyDiscount(double price) {
            return price * 0.9;  // 10% 할인
        }
    }
    
    // 구체적인 전략 2: 20% 할인
    class Discount20Percent implements DiscountStrategy {
        @Override
        public double applyDiscount(double price) {
            return price * 0.8;  // 20% 할인
        }
    }
    
    // 구체적인 전략 3: 고정 금액 할인
    class FixedAmountDiscount implements DiscountStrategy {
        @Override
        public double applyDiscount(double price) {
            return price - 5;  // 5달러 할인
        }
    }
    
    // 컨텍스트 클래스: 할인 전략을 설정하고 적용하는 역할
    class ShoppingCart {
        private DiscountStrategy discountStrategy;  // 할인 전략을 저장
        
        // 할인 전략 설정
        public void setDiscountStrategy(DiscountStrategy discountStrategy) {
            this.discountStrategy = discountStrategy;
        }
        
        // 가격에 할인 전략 적용
        public double calculatePrice(double price) {
            return discountStrategy.applyDiscount(price);
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            ShoppingCart cart = new ShoppingCart();
    
            // 10% 할인 전략 설정
            cart.setDiscountStrategy(new Discount10Percent());
            System.out.println("Price after 10% discount: " + cart.calculatePrice(100));
    
            // 20% 할인 전략 설정
            cart.setDiscountStrategy(new Discount20Percent());
            System.out.println("Price after 20% discount: " + cart.calculatePrice(100));
    
            // 고정 금액 할인 전략 설정
            cart.setDiscountStrategy(new FixedAmountDiscount());
            System.out.println("Price after fixed amount discount: " + cart.calculatePrice(100));
        }
    }
    

    위 예시에서 DiscountStrategy는 전략 인터페이스로, 다양한 할인 전략들이 이 인터페이스를 구현하고 있습니다. ShoppingCart는 컨텍스트로, 할인 전략을 설정하고, calculatePrice() 메소드를 통해 가격에 해당 할인 전략을 적용합니다. 이렇게 하면 클라이언트는 할인 전략을 실행 시점에 바꿀 수 있습니다.


    전략 패턴의 장점

    1. 유연한 알고리즘 변경: 전략 패턴을 사용하면 알고리즘을 클라이언트 코드에서 독립적으로 관리할 수 있어, 실행 시점에서 필요한 전략을 쉽게 변경할 수 있습니다.
    2. 클라이언트 코드 간결화: 클라이언트는 구체적인 알고리즘 구현을 알 필요 없이, 전략 객체만 설정하고 사용하면 되므로 코드가 간결해집니다.
    3. 확장성: 새로운 전략을 추가할 때 기존 코드를 변경할 필요 없이, 새로운 전략 클래스를 추가하여 쉽게 확장할 수 있습니다.
    4. 결합도 낮춤: 전략 패턴은 알고리즘을 캡슐화하여 실행 시점에 변경할 수 있기 때문에, 알고리즘을 사용하는 클래스와 알고리즘을 구현하는 클래스의 결합도를 낮출 수 있습니다.

    전략 패턴의 단점

    1. 전략 클래스의 수 증가: 각 알고리즘마다 새로운 전략 클래스를 만들어야 하기 때문에, 전략이 많아질수록 클래스 수가 증가하게 됩니다. 이는 관리 측면에서 번거로울 수 있습니다.
    2. 복잡한 구조: 간단한 알고리즘을 변경할 때도 전략 패턴을 적용하게 되면 코드 구조가 복잡해질 수 있습니다. 너무 많은 전략을 사용하는 경우엔 오히려 과도한 추상화가 될 수 있습니다.

    결론

    전략 패턴은 알고리즘을 동적으로 교체할 수 있는 유연한 방법을 제공하는 패턴입니다. 알고리즘을 캡슐화하여 클라이언트가 실행 시점에서 전략을 쉽게 선택하고 변경할 수 있게 하며, 유연성과 확장성을 높여줍니다. 특히 다양한 알고리즘을 적용해야 하는 상황에서 유용하게 사용할 수 있습니다.

    하지만 너무 많은 전략을 추가하는 경우에는 코드가 복잡해질 수 있으므로, 전략 패턴을 적용할 때는 적절한 범위에서 사용해야 합니다.


     

    728x90