[디자인패턴] 전략 패턴
Strategy pattern
- 객체의 행위를 바꾸고 싶은 경우 직접 수정하지 않고 전략이라고 부르는 캡슐화한 알고리즘을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴이다.
- 특정 컨텍스트에서 알고리즘을 별도로 분리하는 설계 방법을 의미한다.
- 쉽게 말해서 특정 기능을 수행하는데 다양한 알고리즘이 적용될 수 있을 때, 알고리즘을 별도로 분리하는 설계 방법을 의미하는 것이다.
Strategy pattern의 구조
전략 인터페이스
: 모든 전략 구현체에 대한 공용 인터페이스컨텍스트
: 알고리즘을 실행할 때, 해당 알고리즘과 연결된 전략 객체의 메소드 호출클라이언트
: 특정 전략 객체를 컨텍스트에 전달 함으로써 전략을 등록하거나 변경하여 전략 알고리즘을 실행한 결과를 얻는다.- 전략패턴은 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 지킴 : 새로운 요구사항이 생겼을 때, 기존 코드를 건드리지 않고 새로운 클래스를 추가하면 된다.
단점
-
전략패턴을 적용하면 코드가 길어지고 보기 힘들어진다.
-
컨텍스트에 적용되는 알고리즘이 적다면 분기를 타는 것이 더 좋을 수 있다.