728x90
전략 패턴(Strategy Pattern)은 소프트웨어 디자인 패턴 중 하나로, 행동 관련 디자인 패턴에 속한다. 이 패턴은 객체의 행위를 캡슐화하여 동적으로 행위를 바꿀 수 있게 해주는 패턴이다. 즉, 알고리즘을 클래스에 캡슐화하고, 런타임에 알고리즘을 선택할 수 있도록 하는 것이 전략 패턴의 핵심이다.
전략 패턴의 구조
전략 패턴은 다음과 같은 세 가지 주요 구성 요소로 이루어져 있다.
- Context
- 클라이언트가 사용하는 주요 인터페이스를 제공하는 클래스
- Context는 전략 인터페이스를 참조하고 있으며, 이를 통해 실제 전략을 실행한다.
- 클라이언트는 Context 객체와 상호작용하며, 특정 전략을 선택할 수 있다.
- Strategy(전략) 인터페이스
- 다양한 알고리즘을 정의하는 공통 인터페이스
- 모든 구체적인 전략 클래스들은 이 인터페이스를 구현한다.
- 전략 인터페이스는 특정 알고리즘을 수행하는 메서드를 정의한다.
- Concrete Strategy(구체적인 전략)
- Strategy 인터페이스를 구현하는 구체적인 알고리즘 클래스
- 각 클래스는 서로 다른 알고리즘 또는 행동을 구현한다.
- Context는 이 클래스들 중 하나를 사용하여 특정 행위를 수행한다.
전략 패턴의 동작 방식
- 전략 설정 : 클라이언트는 Context 객체를 생성하고, 사용할 전략(Strategy)을 설정한다.
- 전략 실행 : 클라이언트가 Context 객체를 통해 요청을 하면, Context는 현재 설정된 전략 객체를 사용하여 특정 행동을 수행한다.
- 전략 교체 : 필요에 따라 클라이언트는 다른 전략을 설정할 수 있다. 이때 Context 객체는 새로운 전략에 맞춰 행동을 변경한다.
전략 패턴의 장점
- 유연성 증가: 알고리즘을 동적으로 바꿀 수 있어 코드의 유연성이 증가한다.
- 코드 재사용성: 공통 인터페이스를 사용하여 서로 다른 알고리즘을 캡슐화하므로 코드의 재사용성이 높아진다.
- 유지보수 용이: 알고리즘이 변경될 때, 각 전략 클래스를 독립적으로 수정할 수 있어 유지보수가 쉽다.
예시
// 전략 인터페이스 정의
interface Strategy {
public int[] execute(int[] data);
}
// 구체적인 전략 A
class ConcreteStrategyA implements Strategy {
@Override
public int[] execute(int[] data) {
java.util.Arrays.sort(data);
return data;
}
}
// 구체적인 전략 B
class ConcreteStrategyB implements Strategy {
@Override
public int[] execute(int[] data) {
java.util.Arrays.sort(data);
int n = data.length;
int[] reversedData = new int[n];
for (int i = 0; i < n; i++) {
reversedData[i] = data[n - i - 1];
}
return reversedData;
}
}
// Context 클래스
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int[] executeStrategy(int[] data) {
return strategy.execute(data);
}
}
// 사용 예시
public class StrategyPatternExample {
public static void main(String[] args) {
int[] data = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
// 오름차순 정렬 전략 사용
Context context = new Context(new ConcreteStrategyA());
System.out.print("오름차순 정렬: ");
printArray(context.executeStrategy(data));
// 내림차순 정렬 전략 사용
context.setStrategy(new ConcreteStrategyB());
System.out.print("내림차순 정렬: ");
printArray(context.executeStrategy(data));
}
public static void printArray(int[] data) {
for (int num : data) {
System.out.print(num + " ");
}
System.out.println();
}
}
- Strategy 인터페이스 : Strategy 인터페이스는 execute 메서드를 정의하고 있다. 이 메서드는 데이터를 입력받아 어떤 방식으로든 처리하여 반환한다.
- ConcreteStrategyA 및 ConcreteStrategyB : 두 개의 구체적인 전략 클래스는 Strategy 인터페이스를 구현하며, 각각 오름차순 및 내림차순으로 배열을 정렬하는 로직을 구현하고 있다.
- Context 클래스 : Context 클래스는 Strategy 인터페이스 타입의 필드를 가지고 있으며, 이를 통해 다양한 전략을 실행할 수 있다. setStrategy 메서드를 사용해 동적으로 전략을 변경할 수 있다.
- StrategyPatternExample : main 메서드를 통해 전략 패턴을 사용하는 예시를 보여준다. Context 객체에 서로 다른 전략을 설정하고, 이를 통해 데이터를 처리하는 방식이 어떻게 달라지는지 확인할 수 있다.
전략 패턴의 사용 사례
전략 패턴은 여러 상황에서 유용하게 사용될 수 있다.
- 정렬 알고리즘 : 다양한 정렬 알고리즘을 사용하는 경우 (예: 오름차순, 내림차순, 특정 기준에 따른 정렬)
- 유저 인증 방식 : 여러 가지 인증 방식을 지원해야 하는 경우 (예: 비밀번호 인증, OAuth 인증, 생체 인증 등)
- 가격 계산 방식 : 다양한 가격 정책(예: 할인율, 쿠폰 적용 등)을 동적으로 적용해야 하는 경우
전략 패턴을 사용하면 이러한 다양한 알고리즘을 깔끔하게 관리하고, 유연하게 교체할 수 있다.
반응형
'디자인패턴, OOP' 카테고리의 다른 글
POJO (Plain Old Java Object) (0) | 2025.01.12 |
---|---|
관심사의 분리 (Separation of Concerns, SoC) (0) | 2025.01.12 |
데코레이터 패턴(Decorator Pattern) (0) | 2024.08.14 |
컴포지션(Composition) (1) | 2024.08.12 |
OCP(Open Close Principle) - 개방폐쇄의 원칙 (0) | 2024.08.11 |