출처 : https://www.inflearn.com/course/디자인-패턴
전략 패턴 (Strategy Pattern)
- 여러 알고리즘을 캡슐화하고 상호 교환 가능하게 만드는 패턴.
- 클라이언트가 직접 컨텍스트에서 사용할 알고리즘을 선택한다.
- 생성자에서, 혹은
- 특정 Operator에서 알고리즘을 선택해서 넘겨줄 수 있다.
장점
- 새로운 전략을 추가하더라도 기존 코드를 변경하지 않는다. OCP를 완벽하게 지키고 있다.
- 상속은 한 객체만 가능한데, 이 대신 위임을 사용할 수 있다.
- 런타임에 전략을 변경할 수 있다.
단점
- 복잡도가 증가한다.
- 클라이언트 코드가 구체적인 전략을 알아야 하기 때문에, 의존성이 생긴다.
예시 (as-is)
public class BlueLightRedLight {
private int speed;
public BlueLightRedLight(int speed) {
this.speed = speed;
}
public void blueLight() {
if (speed == 1) {
System.out.println("무 궁 화 꽃 이");
} else if (speed == 2) {
System.out.println("무 궁 화 꽃 이");
} else {
System.out.println("무궁화꽃이");
}
}
public void redLight() {
if (speed == 1) {
System.out.println("피 었 습 니 다.");
} else if (speed == 2) {
System.out.println("피 었 습 니 다.");
} else {
System.out.println("피었습니다.");
}
}
}
public class Client {
public static void main(String[] args) {
BlueLightRedLight blueLightRedLight = new BlueLightRedLight(2);
blueLightRedLight.blueLight();
blueLightRedLight.redLight();
}
}
예시 (to-be : 생성자에서)
public class BlueLightRedLight {
private Speed speed;
public BlueLightRedLight(Speed speed) {
this.speed = speed;
}
public void blueLight() {
speed.blueLight();
}
public void redLight() {
speed.redLight();
}
}
public interface Speed {
void blueLight();
void redLight();
}
public class Normal implements Speed {
@Override
public void blueLight() {
System.out.println("무 궁 화 꽃 이");
}
@Override
public void redLight() {
System.out.println("피 었 습 니 다.");
}
}
public class Fast implements Speed {
@Override
public void blueLight() {
System.out.println("무궁화꽃이");
}
@Override
public void redLight() {
System.out.println("피었습니다.");
}
}
public class Client {
public static void main(String[] args) {
// BlueLightRedLight blueLightRedLight = new BlueLightRedLight(new Normal());
// 익명 클래스로 주입 가능
BlueLightRedLight blueLightRedLight = new BlueLightRedLight(new Speed(){
@Override
public void blueLight() {
System.out.println("BLUE LIGHT");
}
@Override
public void redLight() {
System.out.println("RED RIGHT");
}
});
blueLightRedLight.blueLight();
blueLightRedLight.redLight();
}
}
예시 (to-be : Operator에서)
public class BlueLightRedLight {
public void blueLight(Speed speed) {
speed.blueLight();
}
public void redLight(Speed speed) {
speed.redLight();
}
}
public interface Speed {
void blueLight();
void redLight();
}
public class Normal implements Speed {
@Override
public void blueLight() {
System.out.println("무 궁 화 꽃 이");
}
@Override
public void redLight() {
System.out.println("피 었 습 니 다.");
}
}
public class Fast implements Speed {
@Override
public void blueLight() {
System.out.println("무궁화꽃이");
}
@Override
public void redLight() {
System.out.println("피었습니다.");
}
}
public class Client {
public static void main(String[] args) {
BlueLightRedLight blueLightRedLight = new BlueLightRedLight();
blueLightRedLight.blueLight(new Normal());
blueLightRedLight.redLight(new Fast());
}
}
활용
- Java의 Comparator
List<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(5);
// 내림차순 정렬
Collections.sort(numbers, Comparator.reverseOrder());
Collections.sort(numbers, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
// 오름차순 정렬
Collections.sort(numbers);
Collections.sort(numbers, Comparator.naturalOrder());
- Spring의 Interface은 대부분 전략패턴이 적용되어 있다.
- ApplicationContext : ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, AnnotationConfigApplicationContext, ...
- PlatformTransactionManager : JdbcTransactionManager, JpaTransactionManager, ...
'Design Pattern' 카테고리의 다른 글
[Design Pattern] Factory Method Pattern (팩토리 메서드 패턴) (0) | 2022.11.13 |
---|---|
[Design Pattern] Singleton Pattern (싱글톤 패턴) (0) | 2022.11.12 |
[Design Pattern] Composite Pattern (컴포지트 패턴) (0) | 2022.11.07 |
[Design Pattern] 프록시 (Proxy) (0) | 2022.10.24 |