1 분 소요


Strategy pattern

  • 객체의 행위를 바꾸고 싶은 경우 직접 수정하지 않고 전략이라고 부르는 캡슐화한 알고리즘을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴이다.
  • 특정 컨텍스트에서 알고리즘을 별도로 분리하는 설계 방법을 의미한다.
  • 쉽게 말해서 특정 기능을 수행하는데 다양한 알고리즘이 적용될 수 있을 때, 알고리즘을 별도로 분리하는 설계 방법을 의미하는 것이다.



Strategy pattern의 구조

img1

  • 전략 인터페이스 : 모든 전략 구현체에 대한 공용 인터페이스
  • 컨텍스트 : 알고리즘을 실행할 때, 해당 알고리즘과 연결된 전략 객체의 메소드 호출
  • 클라이언트 : 특정 전략 객체를 컨텍스트에 전달 함으로써 전략을 등록하거나 변경하여 전략 알고리즘을 실행한 결과를 얻는다.
  • 전략패턴은 OOP의 집합체 (OCP, DIP, 다형성, 캡슐화, 추상화)



전략 패턴 구현 코드

  • 블랙 프라이데이에는 50% 할인, 첫 방문 고객은 20%, 일반 방문은 할인 적용X
  • 할인이라는 알고리즘을 DiscountPolicy 라는 인터페이스를 통해 분리해서 관리
//전략 인터페이스
public interface DiscountPolicy {
    double discount(Item item);
}

//blackFriday에 적용할 정책
public class BlackFridayDiscountPolicy implements DiscountPolicy {
    @Override
    public double discount(Item item) {
        return item.getPrice() * 0.5;
    }
}

//아무 이벤트 없는 날에 적용할 정책
public class CommonDiscountPolicy implements DiscountPolicy {
    @Override
    public double discount(Item item) {
        return item.getPrice();
    }
}

//첫 방문자에 적용할 할인 정책
public class FirstDiscountPolicy implements DiscountPolicy {
    @Override
    public double discountPolicy(Item item) {
        return item.getPrice() * 0.8;
    }
}

//컨텍스트
public class Calculator {
    private final DiscountPolicy discountPolicy;

    public Calculator(DiscountPolicy discountPolicy) {
        this.discountPolicy = discountPolicy;
    }

    public double calculate(List<Item> items) {
        double total = 0;
        for (Item item : items) {
            total += discountPolicy.discount(item);
        }
        return total;
    }
}

//클라이언트
public static void main(String[] args) {
    //사용하는 곳에서 전략을 지정
    Calculator cal = new Calculator(new BlackFridayDiscountPolicy());
    cal.calculate(Arrays.asList(
        new Item("banana", 3000),
        new Item("cellPhone", 1000000)
    ));
}



장점

  • 컨텍스트 코드의 변경 없이 새로운 전략을 추가할 수 있다.

  • OCP 지킴 : 새로운 요구사항이 생겼을 때, 기존 코드를 건드리지 않고 새로운 클래스를 추가하면 된다.


단점

  • 전략패턴을 적용하면 코드가 길어지고 보기 힘들어진다.

  • 컨텍스트에 적용되는 알고리즘이 적다면 분기를 타는 것이 더 좋을 수 있다.