디자인패턴

[GOF] 전략(Strategy) 패턴

부에나온다 2024. 3. 17. 15:53

1. Strategy Pattern

  • 실행(런타임) 중에 알고리즘 전략을 선택하여 객체 동작을 실시간으로 바뀌도록 할 수 있게 하는 행위 디자인 패턴
  • 즉, 동작들을 미리 전략으로 정의함으로써 손쉽게 전략을 교체할 수 있는, 변형이 빈번한 경우 적합한 패턴

  1. 전략 알고리즘 객체들 : 알고리즘, 행위, 동작을 객체로 정의한 구현체
  2. 전략 인터페이스 : 모든 전략 구현체에 대한 공용 인터페이스
  3. 컨텍스트 : 알고리즘을 실행해야 할 때마다 해당 알고리즘과 연결된 전략 객체의 메소드를 호출
  4. 클라이언트 : 특정 전략 객체를 컨텍스트에 전달 함으로써 전략을 등록하거나 변경하여 전략 알고리즘을 실행한 결과를 누린다.

  1. 동일 계열의 알고리즘군을 정의하고 (전략 구현체로 정의) , 각각의 알고리즘을 캡슐화하여 (인터페이스로 추상화), 상호교환이 가능하도록 만든다(합성으로 구성)
  2. 알고리즘을 사용하는 클라이언트와 상관없이 독립적으로 (컨텍스트 객체 수정 없이) 다양하게 변경할 수 있게 한다.

2. 전략 패턴 사용 시기

  • 전략 알고리즘의 여러 버전 또는 변형이 필요할 때 클래스화를 통해 관리
  • 알고리즘 코드가 노출되어서는 안 되는 데이터에 엑세스 하거나 데이터를 활용할 때
  • 알고리즘의 동작이 런타임에 실시간으로 교체 되어야할 때
class StrategyInJava {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(2);
        numbers.add(1);
        numbers.add(3);
        numbers.add(5);
        numbers.add(4);

        // sort 메서드의 매개변수로 익명 클래스로 Comparator 객체를 인스턴스화하여
        // 그 안의 compare 메서드 동작 로직(ConcreteStrategy)를 직접 구현하여 할당하는 것을 볼 수 있다.
        Collections.sort(numbers, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
                //비교하는 전략 알고리즘을 지정하여 전략 객체 할당
            }
        });

        System.out.println(numbers);
    }
}

3. 전략 패턴과 템플릿 메소드 턴 비교

유사점

  • 전략 패턴과 템플릿 메소드 패턴은 알고리즘 때에 따라 적용한다는 컨셉으로써, 둘이 공통점을 가지고 있다.
  • 전략 및 템플릿 메소드 패턴은 개방형 폐쇄 원칙을 충족하고 코드를 변경하지 않고 소프트웨어 모듈을 쉽게 확장할 수 있도록 하는 데 사용할 수 있다.

차이점

  • 전략 패턴은 합성(composition)을 통해 해결책을 강구하며, 템플릿 메소드 패턴은 상속(inheritance)을 통해 해결책을 제시
  • 그래서 전략 패턴은 클라이언트와 객체 간의 결합이 느슨한 반면, 템플릿 메소드 패턴은 더 밀접하게 결합
  • 전략패턴은 대부분 인터페이스, 템플릿 메소드 패턴은 주로 추상 클래스나 구체적인 클래스 사용
  • 전략 패턴에서는 전체 전략 알고리즘 변경 가능, 템플릿 메소드 패턴은 일부만 변경되고 나머지는 변경되지 않은 상태로 유지
  • 따라서 단일 상속만이 가능한 자바에서 상속 제한이 있는 템플릿 메소드 패턴보다는, 다양하게 많은 전략을 implements 할수 있는 전략 패턴이 현업에서 많이 사용되는 편이다.