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

20. 중재자 패턴(Mediator Pattern) [Escort GoF의 디자인 패턴]

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

20. 중재자 패턴(Mediator Pattern)

 

20.1 개요

 

 중재자 패턴은 프로그램의 상호작용을 해야 하는 개체들이 서로 복잡하게 관계를 맺고 있을 경우에 상호작용에 관련된 행동을 별도의 형식으로 정의하여 중재하는 개체를 만드는 패턴입니다. 프로그램을 작성하다 보면 복잡한 상호작용을 해야 하는 경우 개체들 간의 결합도는 강하게 되고 유연성이 떨어져서 재사용하기 힘든 경우가 발생합니다. 특히, 하나의 개체에서 다른 개체에게 일방적으로 명령을 하는 것이 아니라 명령을 받는 개체도 특정 조건에서 명령을 내린 개체에게 명령을 내릴 수 있는 경우에는 구조적으로 취약하게 됩니다. 이와 같은 경우에 중재자 패턴을 사용하면 전체적으로 강한 결합도를 부분적으로만 결합도가 강한 상태를 유지하고 많은 부분에서 결합도를 느슨하게 하여 유연성과 재사용성을 높일 수 있습니다.

 

 중재자 패턴에서는 서로 명령을 주고 받을 수 있는 형식이 있다고 했을 때 서로 명령을 주고 받는 부분을 중재하는 형식을 정의하게 됩니다. 그리고 원래 서로 명령을 주고 받았던 개체들은 중재자 개체를 알게 하고 중재자 개체는 이들 개체를 알게 합니다. 이제 특정 개체가 명령을 내릴 필요가 있으면 중재자 개체에게 전달하기만 하면 됩니다. 중재자는 해당 명령을 자신이 알고 있는 개체들 중에 적절한 개체에게 전달만 하면 됩니다. 이처럼 중재자 패턴을 사용하면 복잡한 상호작용을 하기 위한 복잡한 관계를 단순화시킬 수 있게 됩니다.

 

 

 

 

20. 2 시나리오

 

 처음에 EH Camera 회사 객원 감수자를 해 달라는 얘기를 들었을 때에는 강의에 차질이 생길 것 같아 걱정이 되어 고민했었는데 지금에 와서는 두 개의 업무가 서로 시너지를 일으키는 것 같습니다. 강의할 때마다 어떠한 주제로 실습을 시켜야 효과적인지에 대한 고민을 많이 했었는데 요즘은 카메라에 대한 주제로 진행을 많이 하고 있습니다.

 

 지난 주에는 EH Camera 개발 팀에서 만든 카메라 내부 모듈들의 구조를 보완했지요. 카메라를 조리개 우선 모드로 설정을 하였을 때 조리개의 F값을 높이면 셔터 스피드가 느려지고 셔터 스피드 우선 모드로 설정하였을 경우에는 셔터 스피드를 높이면 조리개의 F값이 낮아집니다. EH Camera 내부 모듈을 살펴보니 조리개 모듈에서는 조리개의 F값이 변경되면 카메라의 촬영 모드 관리 모듈에게 촬영 모드를 얻어온 후에 만약, 조리개 우선 모드로 설정이 된 경우에는 셔터 스피드 모듈에게 F값을 전달하게 되어 있더군요. , 셔터 스피드 모듈에서는 셔터 스피드를 조절하면 촬영 모드 관리 모듈에게 촬영 모드를 얻어온 후에 셔터 스피드 우선 모드이면 조리개 모듈에게 셔터 스피드를 전달하고 있었습니다. 개발 팀 얘기를 들어보니 각 모듈을 개발하고 나서 통합 작업을 진행하는데 두 개의 모듈이 서로 자신의 값을 전달하면 자신이 값을 조절한 후에 다시 상대에게 자신의 값을 전달하는 작업을 반복하는 현상때문에 골치가 아팠었다고 하더군요.

 

 저는 개발 팀의 조대화씨에게 카메라 내부 모듈의 상호작용을 제어하는 모듈을 추가하여 단순화시키는 것을 생각해 보자고 제안을 하였습니다. 그리고 오늘 강의에서는 이에 대한 실습을 할꺼예요




AboutMediator.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)

 

//Mediator.h

#pragma once

#include "common.h"

class Mediator

{

public:

             virtual void Change(int mid,int value)=0;

};

 

//InnerModule.h

#pragma once

 

#include "Mediator.h"

class InnerModule

{

             Mediator *mediator;            

             const int mid;

public:

             InnerModule(Mediator *mediator,int mid):mid(mid)

             {

                           this->mediator = mediator;

             }

             void Changed(int value)

             {

                           mediator->Change(mid,value);

             }           

             virtual void SetValue(int value)=0;

             int GetMid()const

             {

                           return mid;

             }

             virtual void AlramChanged(int value)=0;

};

 

//Iris.h

#pragma once

 

#include "InnerModule.h"

class Iris:

             public InnerModule

{

             int iris;

public:

             Iris(Mediator *mediator,int mid):InnerModule(mediator,mid)

             {

                           iris = 0;

             }

             virtual void SetValue(int value)

             {

                           this->iris = value;

                           cout<<"조리개 F:"<<iris<<endl;                   

                           Changed(iris);

             }

             void AlramChanged(int speed)

             {

                           cout<<"셔터 스피드 변경 통보 받음"<<endl;

                           SetValue(10 - speed);                       

             }

};

 

//Shutter.h

#pragma once

 

#include "InnerModule.h"

class Shutter:

             public InnerModule

{

             int speed;

public:

             Shutter(Mediator *mediator,int mid):InnerModule(mediator,mid)

             {

                           speed = 10;

             }

             virtual void SetValue(int value)

             {

                           this->speed = value;

                           cout<<"셔터 스피드:"<<speed<<endl;             

                           Changed(speed);

             }

             void AlramChanged(int iris)

             {

                           cout<<"조리개 F 변경 통보 받음"<<endl;

                           SetValue(10 - iris);                                         

             }

};

 

//InnerMediator.h

#pragma once

 

#include "Mediator.h"

#include "InnerModule.h"

class InnerMediator:

             public Mediator

{

             InnerModule *modules[2];

             int mode;

public:

             void SetInnerModule(int mid,InnerModule *module)

             {

                           modules[mid] = module;

             }

            

             void ChangeMode(int mode)

             {

                           this->mode = mode;

             }

             virtual void Change(int mid,int value)

             {

                           if(mode != mid)

                           {

                                        return;

                           }

                           if(modules[0]->GetMid() == mid)

                           {

                                        modules[1]->AlramChanged(value);                              

                           }

                           else

                           {

                                        modules[0]->AlramChanged(value);

                           }

             }

};

 

//Camera.h

#pragma once

#include "InnerMediator.h"

#include "Iris.h"

#include "Shutter.h"

class Camera

{

             InnerMediator *mediator;

             InnerModule *modules[2];

public:

             Camera(void);

             ~Camera(void);

             void ChangeMode(int mode);

             void SetIris(int iris);

             void SetShutterSpeed(int speed);

};

 

//Camera.cpp

#include "Camera.h"

 

Camera::Camera(void)

{

             mediator = new InnerMediator();

             modules[0] = new Iris(mediator,0);

             modules[1] = new Shutter(mediator,1);

             mediator->SetInnerModule(0,modules[0]);

             mediator->SetInnerModule(1,modules[1]);

             mediator->ChangeMode(0);

}

 

void Camera::ChangeMode(int mode)

{

             if((mode != 0)&&(mode!=1))

             {

                           return;

             }

             if(mode == 0)

             {

                           cout<<"***   조리개 우선 모드   ***"<<endl;

             }

             else

             {

                           cout<<"***   셔터 스피드 우선 모드   ***"<<endl;

             }

             mediator->ChangeMode(mode);

}

void Camera::SetIris(int iris)

{

             modules[0]->SetValue(iris);

}

void Camera::SetShutterSpeed(int speed)

{

             modules[1]->SetValue(speed);

}

Camera::~Camera(void)

{

             delete mediator;

             delete modules[0];

             delete modules[1];

}

 

//Demo.cpp

#include "Camera.h"

int main()

{

             Camera *camera = new Camera();      

             camera->ChangeMode(0);   

             cout<<"1"<<endl;

             camera->SetShutterSpeed(3);            

             cout<<"2"<<endl;

             camera->SetIris(3);

            

 

             camera->ChangeMode(1);   

             cout<<"3"<<endl;

             camera->SetShutterSpeed(4);            

             cout<<"4"<<endl;

             camera->SetIris(4);

             delete camera;

             return 0;

}


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


 

 


반응형