- 문제 사례 설명
- 다양한 접근 방법 및 STRATEGY 패턴
- 기본적인 방법: 분기문에 의한 알고리즘 선택 적용 방식
- 패턴 활용 방식: STRATEGY 패턴
- 샘플 코드
- 구현 관련 사항
- STRATEGY 패턴 정리
정렬을 하기 위한 알고리즘 여러 가지가 준비되어 있다.
여러 알고리즘 중에서 원하는 알고리즘을 선택해서 적용하는 것이 쉽도록 만들어주기 위한 설계 구조는 어떤 것이 바람직할까? 추가 개발된 알고리즘도 쉽게 반영할 수 있는 형태여야 할 것이다.
[소스 25-1] 정수 배열 클래스 자체적으로 여러 정렬 알고리즘 중 선택, 적용 가능하도록 만든 소스
// basic.c
#include <iostream>
#include <stdlib.h>
using namespace std;
#define DEFAULT_MAX_ITEMS 100
#define BUBBLE_SORT_ALGORITHM 1
#define QUICK_SORT_ALGORITHM 2
class IntegerArray
{
public:
IntegerArray(int numOfItems = DEFAULT_MAX_ITEMS)
{
pData_ = new int[numOfItems];
numOfItems_ = numOfItems;
}
void CreateData()
{
for (int i = 0; i < numOfItems_; i++)
{
pData_[i] = rand() % 32768;
}
}
void Sort(int algorithmType)
{
switch (algorithmType)
{
case BUBBLE_SORT_ALGORITHM:
BubbleSort();
break;
case QUICK_SORT_ALGORITHM:
QuickSort();
break;
default:
cout << "No Match Sort Algorithm" << endl;
}
}
protected:
void BubbleSort()
{
cout << "Bubble Sort Algorithm" << endl;
}
void QuickSort()
{
cout << "Quick Sort Algorithm" << endl;
}
private:
int numOfItems_;
int* pData_;
};
void main()
{
IntegerArray a(10);
a.CreateData();
a.Sort(QUICK_SORT_ALGORITHM);
}
|
이런 방식을 적용하게 되면 새로운 종류의 알고리즘이 개발되었을 때 이를 추가 적용하기가 힘들어진다는 문제를 발견하게 될 것이다.
24장에서 살펴보았듯이 객체지향 설계에서 새로운 것을 쉽게 추가할 수 있게 만들어줄 수 있는 대표적인 방법은 클래스 상속 구조를 이용하는 것이었다. 이같은 클래스 상속의 특성을 주어진 문제에 적용해보면 [그림 25-1]과 같은 형태의 클래스 구조를 설계할 수 있을 것이다.
[그림 25-1]의 클래스 구조를 이용하게 되면, 여러 종류의 알고리즘 중 원하는 알고리즘을 선택해서 적용하는 것이 가능할 뿐만 아니라 새로운 종류의 알고리즘이 개발되더라도 기존의 소스코드를 수정하지 않고 이를 적용할 수 있는 장점이 있는데, 이와 같은 클래스 구조를 Stretegy 패턴이라고 한다.
[소스 25-2] 동일 목적의 정렬 알고리즘에 대해 선택, 적용이 용이하도록 Strategy 패턴을 적용
// strategy.c
#include <iostream>
#include <stdlib.h>
using namespace std;
#define DEFAULT_MAX_ITEMS 100
class SortAlgorithm
{
public:
static SortAlgorithm* CreateInstance() { return 0; }
virtual void Sort(int numOfItems, int* pArray) = 0;
protected:
SortAlgorithm(){}
};
class BubbleSort : public SortAlgorithm
{
public:
static BubbleSort* CreateInstance()
{
if (pInstance_ == 0)
pInstance_ = new BubbleSort;
return pInstance_;
}
virtual void Sort(int numOfItems, int* pArray)
{
cout << "Bubble Sort Algorithm" << endl;
}
protected:
BubbleSort()
{
}
private:
static BubbleSort* pInstance_;
};
BubbleSort* BubbleSort::pInstance_ = 0;
class QuickSort : public SortAlgorithm
{
public:
static QuickSort* CreateInstance()
{
if (pInstance_ == 0)
pInstance_ = new QuickSort;
return pInstance_;
}
virtual void Sort(int numOfItems, int* pArray)
{
cout << "QuickSort Algorithm" << endl;
}
protected:
QuickSort()
{
}
private:
static QuickSort* pInstance_;
};
QuickSort* QuickSort::pInstance_ = 0;
class IntegerArray
{
public:
IntegerArray(int numOfItems = DEFAULT_MAX_ITEMS)
{
pData_ = new int[numOfItems];
numOfItems_ = numOfItems;
// default algorithm
pSortAlgorithm_ = BubbleSort::CreateInstance();
}
void CreateData()
{
for (int i = 0; i < numOfItems_; i++)
pData_[i] = rand() % 32768;
}
void PrintOut()
{
for (int i = 0; i < numOfItems_; i++)
cout << pData_[i] << " ";
cout << endl;
}
void SetSortAlgorithm(SortAlgorithm* pNewAlgorithm)
{
pSortAlgorithm_ = pNewAlgorithm;
}
void Sort()
{
pSortAlgorithm_->Sort(numOfItems_, pData_);
}
private:
int* pData_;
int numOfItems_;
SortAlgorithm* pSortAlgorithm_;
};
void main()
{
IntegerArray a(10);
a.CreateData();
a.Sort();
QuickSort* pQuickSort = QuickSort::CreateInstance();
a.SetSortAlgorithm(pQuickSort);
a.Sort();
}
|
반응형
'책정리 > GoF 디자인 패턴' 카테고리의 다른 글
24장 객체 상태 추가에 따른 행위 수행 변경 문제(State패턴) (0) | 2019.02.07 |
---|---|
23장 One Source Multiple Use 문제(Observer 패턴) (0) | 2019.02.07 |
22장 객체의 이전 상태 복원 문제(Memento 패턴) (0) | 2019.02.06 |
21장 M:N 객체 관계의 M:1 단순화 문제(Mediator 패턴) (0) | 2019.02.06 |
20장 동일 자료형의 여러 객체에 대한 순차적 접근 문제(Iterator패턴) (0) | 2019.02.06 |