Design Pattern

[Design Pattern] 전략 패턴 (Strategy Pattern)

ilot 2022. 10. 30. 18:35
출처 : 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, ...