프로그래밍 기술/Escort GoF의 디자인 패턴

19. 반복자 패턴(Iterator Pattern) [Escort GoF의 디자인 패턴]

언제나휴일 2016. 4. 4. 15:06
반응형

19. 반복자 패턴(Iterator Pattern)

 

19.1 개요

 

 프로그래밍하다 보면 개체들을 보관하는 컬렉션 개체를 사용하는 것은 매우 흔한 일입니다. 그리고 컬렉션의 안전성을 유지하기 위해서는 개체를 보관하는 공간을 직접적으로 노출시키지 않게 됩니다. 하지만 사용자의 경우 컬렉션에 보관된 개체의 정보를 검색할 수 있어야 하며 경우에 따라서는 보관된 개체들에 대해 반복된 작업을 수행하기를 원하는 경우가 있습니다. 반복자 패턴은 컬렉션 개체의 내부 저장 공간에 대해 직접적으로 노출하는 것을 막으면서 보관된 개체들에 대해 반복된 작업을 수행할 수 있는 방법을 제공하고자 할 때 사용하는 패턴입니다.

 

 반복자 패턴에서는 컬렉션을 반복 순회하면서 작업을 수행할 필요가 있을 때 순회할 수 있는 도구 개체를 정의합니다. 그리고 사용자는 컬렉션을 통해 순회자 개체를 얻을 수 있으며 순회자를 통해 컬렉션에 보관된 개체들에 대해 반복적인 작업을 수행할 수 있게 합니다. 그리고 컬렉션 형식에 상관없이 순회 방법을 제공할 수 있게 추상화를 한다면 사용자는 여러 컬렉션을 사용함에 있어 같은 방법으로 접근할 수 있어 높은 편의성을 제공할 수 있습니다.

 

 

 

 

19. 2 시나리오

 

 EH Camera 회사 객원 감수자가 된 지도 3개월이 지났습니다. 이제 개발 팀과 대화를 하는 방법도 나아져서 저의 의견을 전달하거나 개발 팀의 의견을 수용할 때 비용이 많이 줄어든 것 같아요. 어제는 개발 팀의 나 망원 씨께서 사진이나 그 외 많은 자료들을 보관하고 관리하는 응용을 작성할 때마다 라이브러리 파트에서는 새로운 컬렉션을 작성하고 응용 파트에서는 이를 사용하는 방법을 다시 익혀야 하는 비용때문에 효과적인 작업을 못하는 것 같다는 얘기를 했어요. 처음에 객원 감수자가 되었을 때에는 이 매핑 씨를 통해 의견을 전달받거나 전달하였는데 처음으로 개발 팀원이 직접 질의를 해 왔어요.

 

 이번 질의는 개발 팀원이 처음으로 직접한 질문이라 제가 하는 작업 공정을 보여주고 싶다는 생각이 들었어요. 그래서 개발 팀의 한 자리를 빌려 작업을 시작하였습니다. 제일 먼저, 컬렉션들이 공통적으로 제공해야 할 것들에 대한 추상적인 약속을 하였습니다. 그리고 보관된 개체들에 대해 반복적인 작업을 할 때 사용할 부분은 별도의 순회자로 추상화하였죠. 추상화 작업을 한 후에는 EH Camera 회사에서 사용하고 있는 여러 종류의 컬렉션의 종류들을 파악하여 추상화 된 컬렉션 기반의 클래스와 추상 순회자 기반의 순회자들을 정의하였습니다. 그리고 간단히 배열 형식의 클래스를 정의하고 배열에 사용할 순회자를 정의한 후에 이를 테스트하는 응용을 작성하였죠. 그리고 설계 문서와 간단한 기술 문서와 데모에 대한 문서를 작성하여 나망원 씨에게 전달하였습니다


반복자 패턴



AboutIterator.zip

//common.h

#pragma once

 

#pragma warning (disable:4996)

#include <iostream>

 

using std::cout;

using std::endl;

#include <vector>

using std::vector;

#include <string>

using std::string;

 

#include <iomanip>

using std::ios;

#include <algorithm>

 

#pragma warning(disable:4482)

 

//Collection.h

#pragma once

#include "common.h"

template <typename T>

class Collection

{

public:

             virtual bool Add(T t)=0;

             virtual void Remove(T t)=0;

             virtual void Clear()=0;

             virtual int Count()const=0;

};

 

//Iterator.h

#pragma once

 

template <typename T>

class Iterator

{

public:

             virtual void Begin()=0;

             virtual bool MoveNext()=0;

             virtual T Current()=0;           

};

 

//Arr.h

#pragma once

#include "Collection.h"

#include "Iterator.h"

 

template <typename T>

class Arr:

             public Collection<T>

{

             T *base;

             const int max_capa;

             int cnt;   

 

             friend class ArrIterator;

             class ArrIterator:

                           public Iterator<T>

             {                         

                           Arr<T> *arr;

                           int index;

             public:                 

                           ArrIterator(Arr<T> *arr)

                           {

                                        this->arr = arr;                                

                                        index = -1;

                           }

                                                    

                           virtual void Begin()

                           {                                      

                                        index = -1;

                           }

                           virtual bool MoveNext()

                           {

                                        index ++;

                                        if(index<arr->cnt)

                                        {

                                                     return true;

                                        }

                                        return false;

                           }

                           virtual T Current()

                           {

                                        return arr->base[index];

                           }

             };

            

public:

             Arr(int max_capa):max_capa(max_capa)

             {

                           base = new T[max_capa];

                           cnt=0;

             }

             ~Arr()

             {

                           delete[] base;

             }

             virtual bool Add(T t)

             {

                           if(IsFull())

                           {

                                        return false;

                           }

                           base[cnt] = t;

                           cnt++;

                           return true;

             }

             virtual void Remove(T t)

             {

                           int index = Find(t);

                          

                           if(index == -1)

                           {

                                        return ;

                           }

                           for(  ; index < (cnt-1) ; index++)

                           {

                                        base[index] =base[index+1];

                           }

                           cnt--;

             }

             virtual void Clear()

             {

                           cnt=0;

             }

             virtual int Count()const

             {

                           return cnt;

             }

             Iterator<T> *MakeIterator()

             {

                           return new ArrIterator(this);

             }

             void RemoveIterator(Iterator<T> *iter)

             {

                           delete iter;

             }

private:

             bool IsFull()const

             {

                           return cnt==max_capa;

             }

             int Find(T t)

             {

                           int index=0;

                           for( index=0 ; index < cnt ; index++)

                           {

                                        if(base[index] == t)

                                        {

                                                     return index;

                                        }

                           }

                           return -1;

             }

};

 

//Tracer.h

#pragma once

#include "Arr.h"

class Tracer

{

public:

             static void DoIt()

             {

                           Arr<int> *arr = new Arr<int>(10);

                           arr->Add(3);

                           arr->Add(6);

                           arr->Add(7);

                          

                           Iterator<int> *iter = arr->MakeIterator();

                           iter->Begin();

                           while(iter->MoveNext())

                           {

                                        cout<<iter->Current()<<endl;

                           }

                           arr->RemoveIterator(iter);

                           delete arr;

             }

};

 

//Demo.cpp

#include "Tracer.h"

int main()

{

             Tracer::DoIt();        

             return 0;

}


IT 전문가로 가는 길 Escort GoF의 디자인 패턴
국내도서
저자 : 장문석
출판 : 언제나휴일 2013.04.01
상세보기


 


반응형