책정리/GoF 디자인 패턴

25장 동일 목적 알고리즘의 선택 적용 문제(Strategy 패턴)

GONII 2019. 2. 7. 20:41
    • 문제 사례 설명
    정렬을 하기 위한 알고리즘 여러 가지가 준비되어 있다.
    여러 알고리즘 중에서 원하는 알고리즘을 선택해서 적용하는 것이 쉽도록 만들어주기 위한 설계 구조는 어떤 것이 바람직할까? 추가 개발된 알고리즘도 쉽게 반영할 있는 형태여야 것이다.
    • 다양한 접근 방법 및 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);
    }
    이런 방식을 적용하게 되면 새로운 종류의 알고리즘이 개발되었을 이를 추가 적용하기가 힘들어진다는 문제를 발견하게 것이다.
    • 패턴 활용 방식: STRATEGY 패턴
    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();
    }
    • 구현 관련 사항
    • STRATEGY 패턴 정리


     
반응형