디자인패턴
[GOF] 전략(Strategy) 패턴
부에나온다
2024. 3. 17. 15:53
1. Strategy Pattern
- 실행(런타임) 중에 알고리즘 전략을 선택하여 객체 동작을 실시간으로 바뀌도록 할 수 있게 하는 행위 디자인 패턴
- 즉, 동작들을 미리 전략으로 정의함으로써 손쉽게 전략을 교체할 수 있는, 변형이 빈번한 경우 적합한 패턴
- 전략 알고리즘 객체들 : 알고리즘, 행위, 동작을 객체로 정의한 구현체
- 전략 인터페이스 : 모든 전략 구현체에 대한 공용 인터페이스
- 컨텍스트 : 알고리즘을 실행해야 할 때마다 해당 알고리즘과 연결된 전략 객체의 메소드를 호출
- 클라이언트 : 특정 전략 객체를 컨텍스트에 전달 함으로써 전략을 등록하거나 변경하여 전략 알고리즘을 실행한 결과를 누린다.
- 동일 계열의 알고리즘군을 정의하고 (전략 구현체로 정의) , 각각의 알고리즘을 캡슐화하여 (인터페이스로 추상화), 상호교환이 가능하도록 만든다(합성으로 구성)
- 알고리즘을 사용하는 클라이언트와 상관없이 독립적으로 (컨텍스트 객체 수정 없이) 다양하게 변경할 수 있게 한다.
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 할수 있는 전략 패턴이 현업에서 많이 사용되는 편이다.