GSI

Iterator 는 반복자로 알고 있는데요.

헤더 퍼스트 책을 보니
한개 이상의 다른 클래스들을 Iterator를 통해서 출력 부분을 동일화 해준다.
실제 데이터 클래스에 반복자 부분을 넣지 않고, Iterator를 직접 생성해서 관리 한다..
이정도로 생각하면 될까요?.

자바 클래스로 샘플 자료가 인터넷에 있던걸 C++로 처리를 해봤는데요.
코드는 아래에 위치 합니다.

여기서 몇가지 궁금증이 발생 합니다.
1. PersonIterator* personiter = (PersonIterator*)persons.CreatIterator(); 를 통해서
   객체를 Iterator로 보내기 위해서요. 내부에 new 를 사용했습니다.
   이때 C++에서는 삭제를 해줘야 하는 번거로움이 발생을 하게 됩니다.
   그래서 참조 형태로 함수에서 인자로 넘기는 것도 고려를 해봤지만. 코드가 깔끔하지 않더라구요.
   다르게 PersonIterator 쪽에 operator=()를 사용해서 Persons 객체를 PersonIterator로 대입하도록 처리도 해봤지만.
   UML의 그림이 조금 이상하게 나와서 ^^..
   자바나 C# 같은 경우는 가비지가 있어서 그런지 모르겠지만 포인터라는 개념 자체가 조금 다르게 되다 보니
   넘길때도 new 해서 객체를 생성해서 넘기게 되니 C++의 형태와 같다는 생각도 들구요.

2. UML을 표현하는데 있어서 아래와 같이 작성을 해봤습니다.
   헤더 파일만 리버스 해서 StarUML에 적용해 봤습니다. 그런데 리버스 할때 상속 구조는 화살표가 생기는데요.
   vector<>를 사용한 부분에서는 제대로 표현이 안되네요.

3. Iterator 패턴을 사용함에 있어서 반복해서 출력해 주거나, 특정 객체를 찾아 주거나, 기타 다른 작업들을
   데이터가 들어가 있는 클래스에 계속 구현하는게 아니라 Iterator를 상속 받아서 여러개를 만들어서 관리를 하는게
   더 좋다고 생각하면 될까요?.. 기존에는 작업을 하나의 데이터 포멧이 있다면 그곳에 드로잉, 탐색, 기타 위치 조정 등에
   대한 코든 코드를 다 넣다 보니 비대해 지고 관리가 힘들어져서 Iterator를 사용해서 분리를 시켜서 적용하면
   더 좋을거 같다는 생각은 드네요.

제가 아직 경험이 부족하니 아래 코드를 보고 잘못 된 점이 있다면 지적 많이 부탁 드려요 ^^..

[코드를 UML로 표현]

사용자 삽입 이미지

/** 코드 구현부 시작  **/

// 헤더 파일///////////////////////////////////////////////////////////////
#pragma once

class Person;
class Persons;

/************************************************************************/
/*                                                                      */
/************************************************************************/
class Iterator
{
public:
 Iterator() {}
 ~Iterator() {}

 virtual bool hasNext() = 0;
 virtual Person* Next() = 0;
};


/************************************************************************/
/*                                                                      */
/************************************************************************/
class PersonIterator : public Iterator
{
public:
 PersonIterator() {}
 PersonIterator( Persons* p );
 ~PersonIterator();

 PersonIterator& operator = ( Persons* p );

 bool  hasNext();
 Person*  Next();

protected:
 Persons*     m_pPersons;
// vector< Person >*   vperson;
// vector< Person >::iterator vpersoniter;
 int       number;
};


/************************************************************************/
/*                                                                      */
/************************************************************************/
class Person
{
public:
 Person( string name );
 ~Person();

 void  Print();
 string&  getName();

public:
 string m_name;
};


/************************************************************************/
/*                                                                      */
/************************************************************************/
class Aggregate
{
public:
 Aggregate() {}
 ~Aggregate() {}

 virtual void iterator( Iterator* iter ) {}
};


/************************************************************************/
/*                                                                      */
/************************************************************************/
class Persons : public Aggregate
{
public:
 Persons();
 ~Persons();

 void  AddPerson( Person& p );
 Iterator* CreatIterator();
public:
 int     m_Number;
 vector< Person > m_Array;
};

// 소스 파일///////////////////////////////////////////////////////////////

// IteratorPattern.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"
#include "IteratorPattern.h"

/************************************************************************/
/*                                                                      */
/************************************************************************/
Person::Person( string name )
{
 m_name = name;
}

Person::~Person()
{
}

string& Person::getName()
{
 return m_name;
}

void Person::Print()
{
 cout << "이름:" << m_name.c_str() << endl;
}


/************************************************************************/
/*                                                                      */
/************************************************************************/
PersonIterator::PersonIterator( Persons* p )
{
 m_pPersons  = p;
 number   = 0;
}

PersonIterator::~PersonIterator()
{
}

PersonIterator& PersonIterator::operator = ( Persons* p )
{
 m_pPersons  = p;
// vperson   = &rhs.m_Array;
// vpersoniter  = vperson->begin();
 number   = 0;
 return *this;
}

bool PersonIterator::hasNext()
{
 if( number < (int)m_pPersons->m_Array.size() )
  return true;
 else
  return false;
}

Person* PersonIterator::Next()
{
 vector< Person >::iterator iter = m_pPersons->m_Array.begin();
 iter += number++;
 return (Person*)&(*iter);
}


/************************************************************************/
/*                                                                      */
/************************************************************************/
Persons::Persons()
{
 m_Number = 0;
 m_Array.clear();
}

Persons::~Persons()
{
}

void Persons::AddPerson( Person& p )
{
 m_Array.push_back( p );
}

Iterator* Persons::CreatIterator()
{
 PersonIterator* pi = new PersonIterator( this );
 return pi;
}

/** 코드 구현부 끝 **/

/** 메인 시작 **/
int _tmain(int argc, _TCHAR* argv[])
{
    Persons persons;

    persons.AddPerson( Person( "손병욱" ) );
    persons.AddPerson( Person( "천성구" ) );
    persons.AddPerson( Person( "박창준" ) );

    PersonIterator* personiter = (PersonIterator*)persons.CreatIterator();

    while( personiter->hasNext() )
    {
        Person* pp = personiter->Next();
        if( pp )
        {
            pp->Print();
        }
    }
    delete personiter;

    return 0;
}
/** 메인 끝 **/

Posted by gsi
: