GSI

중재자 ( Mediator )

의도

  • 한 집합에 속해 있는 객체의 상호작용을 캡슐화
  • 객체 사이의 소결합 (loose coupling)
  • 객체의 상호작용을 독립적으로 다양화 시킴

동기

  • 객체 지향 개발 방법에 있어서 행동을 여러개의 객체로 분산시키고 있습니다.
  • 분할된 객체들의 관리가 제대로 되지 못하면 객체 간 상호작용의 급증으로 인한 오류를 범할 수 있습니다.

MFC의 개발을 하다 보면 화면 UI 및 데이터간의 연동이 필요 하게 됩니다.
리스트 박스의 셀렉트가 되면 해당 에디터 박스에 출력을 하고, 그 반대의 경우도 존재 할 수 있습니다.
이러한 경우 객체 대 객체 간의 데이터 접근 방법을 사용하게 되면 결합도가 높아지면서 코드가 복잡해 지고,
재 사용성을 떨어 트리게 됩니다.

이때, 중재자 객체를 활용하면 여러 객체가 처리 하는 행동들을 하나의 객체에서 처리 하게 되면서 이런 문제점들을 해결할 수 있습니다.

중재자 객체는 객체 그룹 간의 상호작용을 제어하고 조화를 이루는 역활을 합니다.
즉, 객체 사이의 연결 정도가 줄어 들게 됩니다.

하나의 예를 들어 보겠습니다.
리스트 박스와 에디터 박스가 있다고 합시다.

  1. 리스트 상자는 지시자 객체에게 자신이 변경되었음을 통보 합니다.
  2. 지시자는 리스트 상자에서 선택된 부분이 무엇인지 알아옵니다.
  3. 지시자는 입력 창에 선택 부분을 전달합니다.
  4. 입력 창에는 어떤 값이 포함됩니다. 지시자는 관련된 버튼을 활성화 시킵니다.

UML 내용을 한번 볼께요.

사용자 삽입 이미지

위의 것은 실제적인 구현한 내용을 토대로 제작된 UML 과 아래의 기본 구조모양의 UML을 보실 수 있습니다.

자세한 소스 코드는 오늘은 올리기 힘들듯 합니다. -.-
한번 데모로 작성해 보고 올려야 할듯 합니다.
Posted by 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
: