세줄 정리

  • 각 케이스에 따라 다른 알고리즘이 사용될 때
  • 케이스가 추가될 때마다 코드를 수정하는 것이 복잡해짐
  • 이때, 케이스에 따른 알고리즘을 객체로 분리

다이어그램

strategy pattern uml

  • Strategy : 전략을 추상화시킨 인터페이스
  • Concrete Strategy : 각 케이스에 맞는 클래스로 구체적인 알고리즘을 제공
  • Context : Strategy를 실행 시킴

예시

상황

  • 손님에 따라 다른 할인 전략을 제공하려고 한다
  • 첫 손님에게 10% 할인
  • 덜 신선한 상품은 20% 할인을 제공

디자인 패턴 적용하지 않은 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Public class Calculator {
    public int calculate(boolean firstGuest, List<Item> Items) {
        int sum = 0;
        for(Item item : items) {
            if (firstGuest) {
                sum +=Item.getPrice() * 0.9// 첫 손님 10% 할인
            } else if(!Item.isFresh()) {
                sum += item.getPrice() * 0.8// 덜 신선한 상품 20% 할인
            } else {
                sum += item.getPrice();
            }
        }
        return sum;
    }
}
 
cs

위 코드의 문제

  • 할인 전략이 추가될때마다, 메서드를 수정하는 것이 어려워짐
  • calculate 메소드에 파라미터가 추가되어야 하며
  • else if 문이 하나 추가되어야함

디자인 패턴 적용한 경우

  • 케이스에 따른 전략을 클래스로 나눈 후에
  • 각 전략을 콘텍스트에서 실행
  • 각 전략은 콘텍스트에서 직접 선택되지 않고, 콘텍스트 사용자가 생성자를 통해 전달
  • 할인 정책이 추가될경우, 새로운 Strategy 클래스를 만들면 됨

Context 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Public class Calculator {
 
    private DiscountStrategy discountStrategy; // 할인 정책을 인터페이스로 가져옴
 
    public Calculator(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy; // 할인 정책 생성자를 통해 전달
}
 
public int calculate(List<Item> items) {
    int sum = 0;
    for(Item item : items) {
        sum += discountStrategy.getDiscountPrice(item);
}    
return sum;
}
}
 
cs

Strategy 인터페이스

1
2
3
4
5
6
public interface DiscountStrategy {
 
    int getDiscountPrice(Item item);
 
}
 
cs

Strategy 콘크리트 클래스

1
2
3
4
5
6
7
public class FirstGuestDiscountStrategy implements DiscountStrategy {
    @Override
    public int getDiscountPrice(Item item) {
        return item.getPrice() * 0.9;
}
}
 
cs

calculator 실행 코드

1
2
3
4
5
6
7
8
9
10
private DiscountStrategy strategy;
 
 
public int firstCustomerCalculate() { // 첫 고객이 구매할때
    strategy = new FirstGuestDiscountStrategy();
    Calculator cal = new Calculator(strategy);
 
    return cal.calculate(Items);
}
 
cs

출처

+ Recent posts