본문 바로가기

디자인 패턴

4. 전략 패턴

전략 패턴이란?

위키피디아에서는 전략 패턴을 다음과 같이 설명하고 있다.

  • 전략 패턴(strategy pattern) 또는 정책 패턴(policy pattern)은 실행 중에 알고리즘을 선택할 수 있게 하는 행위 소프트웨어 디자인 패턴 
  • 알고리즘들을 정의하고 각 알고리즘을 캡슐화하며 이 알고리즘들을 해당 계열 안에서 상호 교체가 가능하게 만든다
  • 전략은 알고리즘을 사용하는 클라이언트와는 독립적으로 다양하게 만든다
  • 유연하고 재사용 가능한 객체 지향 소프트웨어를 어떻게 설계하는지 기술하기 위해 디자인 패턴의 개념을 보급시킨 디자인 패턴(Gamma 등)이라는 영향력 있는 책에 포함된 패턴들 가운데 하나

전략패턴이란 특정 컨텍스트에서 알고리즘을 별도로 분리하는 설계 방법을 의미합니다.

다음으로 예시를 한번 살펴보겠습니다.

전략 패턴이 적용되지 않은 코드

최근에 대출을 받아서 대출로 예시를 들어보겠습니다.

public class Loan {
    private Money loanMoney;

    public double calculate(boolean isFirstSuceess, boolean isSencodeSuccess, boolean isThirdSuccess) {
        double sum = 0;

        if (isFirstSuceess) {
            sum += loanMoney.getPrice() * 0.9;
        } else if (isSencodeSuccess) {
            sum += loanMoney.getPrice() * 0.8;
        } else if (isThirdSuccess) {
            sum += loanMoney.getPrice() * 0.7;
        }

        return sum;
    }
}

public class Money {
    private final int price;

    public Money(int price) {
        this.price = price;
    }

    public int getPrice() {
        return price;
    }
}

전략 패턴이 적용된 코드

위에서 말한 할인이라는 알고리즘을 DiscountPolicy 라는 인터페이스를 통해 분리하여 관리하겠습니다.

public interface DiscountPolicy {
    double calculateWithDisCountRate(Money money);
}

public class FirstDiscount implements DiscountPolicy {
    @Override
    public double calculateWithDisCountRate(Money money) {
        return money.getPrice() * 0.9;
    }
}

public class SecondDiscount implements DiscountPolicy {
    @Override
    public double calculateWithDisCountRate(Money money) {
        return money.getPrice() * 0.8;
    }
}

public class ThirdDiscount implements DiscountPolicy {
    @Override
    public double calculateWithDisCountRate(Money money) {
        return money.getPrice() * 0.7;
    }
}

가격정책이라는 인터페이스를 생성합니다.

public class Loan {
    private final Money money;
    private DiscountPolicy discountPolicy;

    public Loan(Money money, DiscountPolicy discountPolicy) {
        this.money = money;
        this.discountPolicy = discountPolicy;
    }

    public double calculate() {
        double sum = 0;
        sum += this.discountPolicy.calculateWithDisCountRate(this.money);

        return sum;
    }
    
    public void setDiscountPolicy(DiscountPolicy discountPolicy) {
        this.discountPolicy = discountPolicy;
    }
}

기존의 로직을 수정합니다.

public class LoanController {
    public void main(String[] args) {
        Loan loan = new Loan(new Money(1000), new FirstDiscount());
        loan.calculate();
        loan.setDiscountPolicy(new SecondDiscount());
        loan.calculate();
    }
}

'디자인 패턴' 카테고리의 다른 글

Worker Thread Pattern  (0) 2022.08.24
데코레이터(Decorator) 패턴  (0) 2022.07.31
3. 이터레이터 패턴  (0) 2022.07.12
2. Adapter Pattern  (0) 2022.07.08
1. Factory Pattern  (0) 2022.07.05