반응형
전략 패턴 (Strategy Pattern)
전략 패턴은 행위 패턴 중 하나로, 알고리즘을 각각의 클래스에 캡슐화하여, 클라이언트가 알고리즘을 독립적으로 변경할 수 있도록 합니다. 이를 통해 알고리즘의 변화가 클라이언트 코드에 영향을 미치지 않도록 합니다.
전략 패턴의 특징
- 알고리즘 캡슐화: 알고리즘을 독립적인 클래스로 캡슐화하여 교체가 용이합니다.
- 유연성 제공: 런타임에 알고리즘을 동적으로 변경할 수 있습니다.
- 클래스 분리: 클라이언트 코드와 알고리즘 클래스를 분리하여 코드의 가독성과 유지보수성을 높입니다.
전략 패턴의 구조
- Context: 전략을 사용하는 클래스
- Strategy: 알고리즘을 정의하는 인터페이스
- ConcreteStrategy: 구체적인 알고리즘을 구현하는 클래스
전략 패턴 UML 다이어그램
+-----------+ +------------+
| Context | | Strategy |
|-----------| |------------|
| -strategy |<----->| +algorithm |
+-----------+ +------------+
|
| uses
|
v
+-----------------+
| ConcreteStrategy|
|-----------------|
| +algorithm |
+-----------------+
전략 패턴 구현 예제
다음 예제는 전략 패턴을 사용하여 다양한 정렬 알고리즘을 구현합니다.
전략 인터페이스 정의
#include <iostream>
#include <vector>
#include <algorithm>
// 전략 인터페이스
class SortStrategy {
public:
virtual void sort(std::vector<int>& data) = 0;
virtual ~SortStrategy() = default;
};
구체적인 전략 클래스 구현
// 버블 정렬 전략
class BubbleSort : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
for (size_t i = 0; i < data.size() - 1; ++i) {
for (size_t j = 0; j < data.size() - i - 1; ++j) {
if (data[j] > data[j + 1]) {
std::swap(data[j], data[j + 1]);
}
}
}
}
};
// 선택 정렬 전략
class SelectionSort : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
for (size_t i = 0; i < data.size() - 1; ++i) {
size_t min_idx = i;
for (size_t j = i + 1; j < data.size(); ++j) {
if (data[j] < data[min_idx]) {
min_idx = j;
}
}
std::swap(data[i], data[min_idx]);
}
}
};
// 삽입 정렬 전략
class InsertionSort : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
for (size_t i = 1; i < data.size(); ++i) {
int key = data[i];
size_t j = i - 1;
while (j >= 0 && data[j] > key) {
data[j + 1] = data[j];
--j;
}
data[j + 1] = key;
}
}
};
Context 클래스 정의
// Context 클래스
class SortContext {
private:
SortStrategy* strategy;
public:
SortContext(SortStrategy* strategy) : strategy(strategy) {}
void setStrategy(SortStrategy* newStrategy) {
strategy = newStrategy;
}
void sort(std::vector<int>& data) {
strategy->sort(data);
}
};
전략 패턴 사용 예제
int main() {
std::vector<int> data = {5, 2, 9, 1, 5, 6};
BubbleSort bubbleSort;
SelectionSort selectionSort;
InsertionSort insertionSort;
SortContext context(&bubbleSort);
context.sort(data);
std::cout << "Bubble Sort: ";
for (int num : data) {
std::cout << num << " ";
}
std::cout << std::endl;
data = {5, 2, 9, 1, 5, 6};
context.setStrategy(&selectionSort);
context.sort(data);
std::cout << "Selection Sort: ";
for (int num : data) {
std::cout << num << " ";
}
std::cout << std::endl;
data = {5, 2, 9, 1, 5, 6};
context.setStrategy(&insertionSort);
context.sort(data);
std::cout << "Insertion Sort: ";
for (int num : data) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
이 예제에서 SortContext
클래스는 다양한 정렬 알고리즘을 사용하여 데이터를 정렬합니다. SortStrategy
인터페이스를 통해 다양한 정렬 전략을 정의하고, SortContext
는 런타임에 전략을 변경하여 데이터를 정렬할 수 있습니다.
실습 문제
문제 1: 전략 패턴을 사용하여 다양한 검색 알고리즘 구현
전략 패턴을 사용하여 선형 검색과 이진 검색을 구현하고, 런타임에 검색 알고리즘을 선택하여 데이터를 검색하는 프로그램을 작성하세요.
해설:
전략 인터페이스 정의
#include <iostream>
#include <vector>
// 검색 전략 인터페이스
class SearchStrategy {
public:
virtual int search(const std::vector<int>& data, int target) = 0;
virtual ~SearchStrategy() = default;
};
구체적인 전략 클래스 구현
// 선형 검색 전략
class LinearSearch : public SearchStrategy {
public:
int search(const std::vector<int>& data, int target) override {
for (size_t i = 0; i < data.size(); ++i) {
if (data[i] == target) {
return i;
}
}
return -1;
}
};
// 이진 검색 전략
class BinarySearch : public SearchStrategy {
public:
int search(const std::vector<int>& data, int target) override {
size_t left = 0;
size_t right = data.size() - 1;
while (left <= right) {
size_t mid = left + (right - left) / 2;
if (data[mid] == target) {
return mid;
} else if (data[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
};
Context 클래스 정의
// Context 클래스
class SearchContext {
private:
SearchStrategy* strategy;
public:
SearchContext(SearchStrategy* strategy) : strategy(strategy) {}
void setStrategy(SearchStrategy* newStrategy) {
strategy = newStrategy;
}
int search(const std::vector<int>& data, int target) {
return strategy->search(data, target);
}
};
전략 패턴 사용 예제
int main() {
std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
LinearSearch linearSearch;
BinarySearch binarySearch;
SearchContext context(&linearSearch);
int target = 5;
int index = context.search(data, target);
std::cout << "Linear Search: Element " << target << " found at index " << index << std::endl;
context.setStrategy(&binarySearch);
index = context.search(data, target);
std::cout << "Binary Search: Element " << target << " found at index " << index << std::endl;
return 0;
}
이제 10일차의 학습을 마쳤습니다. 전략 패턴의 다양한 구현 방법과 활용 사례에 대해 상세히 학습하고 실습 문제를 풀어보았습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "옵저버 패턴"에 대해 학습하겠습니다.
반응형