ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Behavioral Design Pattern - Strategy(전략) 파헤치기
    Java/디자인패턴 2024. 10. 25. 15:22
    반응형

    Strategy 패턴은 객체의 행위를 유연하게 변경할 수 있도록 하는 디자인 패턴 중 하나입니다. 이 패턴은 알고리즘 군(群)을 정의하고, 이 알고리즘을 캡슐화하여 필요에 따라 교체할 수 있도록 합니다. Strategy 패턴을 사용하면 객체의 행위(behavior)를 클래스로 캡슐화하여 동적으로 알고리즘을 교체할 수 있습니다.

     

     

     

    Strategy 패턴의 구조

    1. Context: 전략을 사용하는 클래스입니다. 특정 Strategy 인터페이스에 의존하고, 런타임에 적절한 Strategy 객체를 선택합니다.
    2. Strategy: 알고리즘을 캡슐화하는 인터페이스입니다. 다양한 알고리즘이 이 인터페이스를 구현하여 특정 행위를 정의합니다.
    3. Concrete Strategy: 구체적인 알고리즘을 구현하는 클래스입니다. Strategy 인터페이스를 구현하여 다양한 행위를 정의합니다.

     

    1. Strategy 인터페이스 정의

    먼저 할인 전략을 정의할 인터페이스를 만듭니다

    public interface DiscountStrategy {
        double applyDiscount(double price);
    }

    DiscountStrategy는 할인 전략의 기본 인터페이스입니다. applyDiscount 메서드를 통해 각 할인 전략 클래스에서 구체적인 할인 방식을 구현하도록 합니다.

     

     

    2. Concrete Strategy 클래스 정의

    이제 다양한 할인 전략을 구현해 보겠습니다.

    // 할인 없음 전략
    public class NoDiscount implements DiscountStrategy {
        @Override
        public double applyDiscount(double price) {
            return price;
        }
    }
    
    // 퍼센티지 할인 전략
    public class PercentageDiscount implements DiscountStrategy {
        private double percentage;
    
        public PercentageDiscount(double percentage) {
            this.percentage = percentage;
        }
    
        @Override
        public double applyDiscount(double price) {
            return price * (1 - percentage / 100);
        }
    }
    
    // 고정 금액 할인 전략
    public class FixedDiscount implements DiscountStrategy {
        private double discount;
    
        public FixedDiscount(double discount) {
            this.discount = discount;
        }
    
        @Override
        public double applyDiscount(double price) {
            return Math.max(0, price - discount);
        }
    }
    • NoDiscount 클래스는 원래 가격을 그대로 반환합니다.
    • PercentageDiscount 클래스는 주어진 퍼센티지로 할인된 가격을 계산합니다.
    • FixedDiscount 클래스는 고정 금액을 할인한 가격을 계산하며, 최소 0 이상의 값만 반환합니다.

     

    3. Context 클래스 정의

    이제 DiscountContext라는 클래스에서 다양한 할인 전략을 선택하여 사용할 수 있도록 합니다.

    public class DiscountContext {
        private DiscountStrategy strategy;
    
        public DiscountContext(DiscountStrategy strategy) {
            this.strategy = strategy;
        }
    
        public void setStrategy(DiscountStrategy strategy) {
            this.strategy = strategy;
        }
    
        public double getDiscountedPrice(double price) {
            return strategy.applyDiscount(price);
        }
    }

    DiscountContext 클래스는 strategy 필드에 할당된 할인 전략을 사용하여 가격을 계산합니다. setStrategy 메서드를 통해 전략을 동적으로 변경할 수 있습니다.

     

     

    4. 예제 실행

    이제 다양한 전략을 활용해 보겠습니다.

    public class Main {
        public static void main(String[] args) {
            double originalPrice = 1000.0;
    
            System.out.println("Original Price: " + originalPrice);
    
            // No Discount
            DiscountContext context = new DiscountContext(new NoDiscount());
            System.out.println("No Discount: " + context.getDiscountedPrice(originalPrice));
    
            // Percentage Discount
            context.setStrategy(new PercentageDiscount(10));
            System.out.println("10% Discount: " + context.getDiscountedPrice(originalPrice));
    
            // Fixed Amount Discount
            context.setStrategy(new FixedDiscount(200));
            System.out.println("Fixed $200 Discount: " + context.getDiscountedPrice(originalPrice));
        }
    }

    출력 결과

    Original Price: 1000.0
    No Discount: 1000.0
    10% Discount: 900.0
    Fixed $200 Discount: 800.0

    Strategy 패턴의 장점과 단점

    장점:

    1. 유연성: 알고리즘을 런타임에 교체할 수 있어 유연성이 높아집니다.
    2. 단일 책임 원칙: 각 전략이 하나의 특정한 행위를 담당하여 유지보수가 쉬워집니다.
    3. 확장성: 새로운 전략을 추가할 때 기존 코드를 수정할 필요 없이 새 클래스를 추가하면 됩니다.

    단점:

    1. 복잡성 증가: Strategy 패턴을 적용하면 클래스가 늘어나 복잡도가 증가할 수 있습니다.
    2. 클라이언트와의 결합: 클라이언트 코드에서 구체적인 전략을 선택하거나 교체해야 하므로 약간의 결합도가 발생할 수 있습니다.

    이처럼 Strategy 패턴을 통해 다양한 할인 정책을 유연하게 적용할 수 있고, 새로운 할인 정책을 추가할 때 기존 코드를 수정하지 않고도 쉽게 확장할 수 있습니다.

    반응형

    댓글

Designed by Tistory.