반응형
1. 전략(Strategy) 패턴이란?
전략 패턴(Strategy Pattern)은 특정 행동(기능)을 캡슐화하여 동적으로 변경할 수 있도록 해주는 디자인 패턴입니다. 이 패턴은 행위(Behavioral) 디자인 패턴 중 하나로, 실행 중에 알고리즘이나 로직을 바꿀 수 있게 해줍니다.
특징
- 유연한 행동 변경: 클래스의 행동을 수정하지 않고 실행 시점에 다른 전략(알고리즘)으로 교체할 수 있습니다.
- 인터페이스 기반 설계: 전략 패턴은 공통된 인터페이스를 제공하고, 이를 구현하여 다양한 전략을 만듭니다.
- OCP (Open-Closed Principle): 확장에는 열려 있고, 수정에는 닫혀 있는 원칙을 따릅니다.
2. 전략 패턴의 클래스 다이어그램
+---------------------+
| Context |
|---------------------|
| - strategy:Strategy |
| |
| + setStrategy() |
| + executeStrategy() |
+---------------------+
+---------------------+ +-------------------------+
| Strategy |<----->| ConcreteStrategyA |
|---------------------| |-------------------------|
| + execute():void | | + execute():void |
+---------------------+ +-------------------------+
+---------------------+ +-------------------------+
| ConcreteStrategyB | | ConcreteStrategyC |
|---------------------| |-------------------------|
| + execute():void | | + execute():void |
+---------------------+ +-------------------------+
설명
- Strategy: 공통된 행동(전략)을 정의하는 인터페이스입니다.
- ConcreteStrategy:
Strategy
를 구현한 구체적인 전략 클래스입니다. - Context: 전략을 사용하는 역할로, 전략 객체를
setStrategy()
메서드를 통해 교체할 수 있습니다.
3. 전략 패턴 구현 예제
문제 상황
다양한 정렬 방식을 필요로 하는 프로그램을 가정합니다. 사용자는 실행 중에 정렬 전략(오름차순, 내림차순, 사용자 정의)을 변경할 수 있습니다.
코드 예제
// 1. 전략 인터페이스
interface SortStrategy {
void sort(int[] numbers);
}
// 2. 구체적인 전략들
class AscendingSort implements SortStrategy {
@Override
public void sort(int[] numbers) {
System.out.println("오름차순 정렬");
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
}
}
class DescendingSort implements SortStrategy {
@Override
public void sort(int[] numbers) {
System.out.println("내림차순 정렬");
Integer[] temp = Arrays.stream(numbers).boxed().toArray(Integer[]::new);
Arrays.sort(temp, Collections.reverseOrder());
System.out.println(Arrays.toString(temp));
}
}
class CustomSort implements SortStrategy {
@Override
public void sort(int[] numbers) {
System.out.println("사용자 정의 정렬 (홀수 우선)");
Arrays.sort(numbers);
Arrays.sort(numbers, (a, b) -> (a % 2 == b % 2) ? a - b : (a % 2 == 0) ? 1 : -1);
System.out.println(Arrays.toString(numbers));
}
}
// 3. Context 클래스
class SortContext {
private SortStrategy strategy;
public void setStrategy(SortStrategy strategy) {
this.strategy = strategy;
}
public void executeStrategy(int[] numbers) {
if (strategy == null) {
System.out.println("전략이 설정되지 않았습니다.");
return;
}
strategy.sort(numbers);
}
}
// 4. 테스트 코드
public class StrategyPatternExample {
public static void main(String[] args) {
SortContext context = new SortContext();
int[] numbers = {5, 3, 8, 1, 2, 7};
// 오름차순 정렬
context.setStrategy(new AscendingSort());
context.executeStrategy(numbers);
// 내림차순 정렬
context.setStrategy(new DescendingSort());
context.executeStrategy(numbers);
// 사용자 정의 정렬
context.setStrategy(new CustomSort());
context.executeStrategy(numbers);
}
}
출력 결과
오름차순 정렬
[1, 2, 3, 5, 7, 8]
내림차순 정렬
[8, 7, 5, 3, 2, 1]
사용자 정의 정렬 (홀수 우선)
[1, 3, 5, 7, 2, 8]
4. 전략 패턴의 실제 사용 사례
- 정렬 알고리즘 선택: 실행 시점에서 사용자나 조건에 따라 정렬 방식을 변경.
- 데이터 압축: ZIP, RAR, TAR 등 다양한 압축 전략 적용.
- 결제 시스템: 신용카드, PayPal, 계좌이체 등 다양한 결제 수단을 선택.
- 그래픽 렌더링: CPU 렌더링, GPU 렌더링 등 실행 환경에 따라 렌더링 전략 변경.
5. 결론
전략 패턴은 알고리즘이나 로직을 유연하게 변경해야 할 때 매우 유용합니다. 이 패턴을 사용하면 코드 수정 없이 새로운 전략을 추가하거나 교체할 수 있어 유지보수와 확장성이 뛰어납니다.
반응형
'JAVA > JAVA Design Pattern' 카테고리의 다른 글
JAVA 옵저버(Observer) 패턴 (0) | 2025.01.01 |
---|---|
JAVA 플라이웨이트(Flyweight) 패턴: 메모리 절약을 위한 공유 객체 사용 (0) | 2024.12.29 |
JAVA 브리지(Bridge) 패턴 (0) | 2024.12.28 |
JAVA 퍼사드(Facade) 패턴, 복잡한 시스템을 단순화하는 방법 (0) | 2024.12.27 |
JAVA 접근 제어를 위한 프록시(Proxy) 패턴 (0) | 2024.12.26 |