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

7. 가교 패턴(Bridge Pattern) [Escort GoF의 디자인 패턴]

언제나휴일 2016. 4. 4. 13:50
반응형

7. 가교 패턴(Bridge Pattern)

 

7.1 개요

 

 가교 패턴은 추상적 개념과 구체적 구현 사이의 종속성을 제거하여 목적에 맞게 다양한 구현 방법을 사용하도록 제공하는 패턴입니다. 프로그램하다 보면 일반화 관계로 설계하였을 때 기반 클래스에서 파생하는 클래스가 너무 많아지는 경우가 발생합니다. 그리고 다시 파생 클래스를 기반으로 하는 파생 클래스가 많아지는 경우도 발생하지요.

 

 예를 들어, 사람이라는 기반 클래스가 있다고 가정합시다. 그리고 사람에서 파생한 학생과 학부모, 강사 등이 있습니다. 학생 중에는 피아노를 칠 수 있는 학생과 야구를 할 줄 아는 학생, 피아노와 야구를 할 줄 하는 학생 등이 있을 수 있겠죠. 학부모와 강사도 마찬가지일 것입니다. 이를 일반화 관계로 표현하다 보면 파생되는 계층도 깊어지고 구현해야 할 파생 클래스의 수도 너무 많아지게 됩니다. 이 같은 경우에 야구를 하는 것과 피아노를 치는 것처럼 구체적인 구현을 분리하는 것입니다. 그리고 학생 개체가 구체적 구현으로 분리된 피아노를 치는 개체를 포함하여 피아노를 치는 학생을 만들 수도 있고 야구를 하는 개체를 포함하여 야구를 하는 학생을 만들 수도 있게 됩니다. 물론, 학생 개체에 피아노를 치는 개체와 야구를 하는 개체를 포함하면 피아노와 야구를 할 수 있는 학생이 되겠죠. 학부모 개체에 피아노를 치는 개체를 포함하면 피아노를 칠 수 있는 학부모가 됩니다. , 추상적 개념에 해당하는 부분은 기반 클래스 사람과 파생 클래스 학생, 학부모, 강사로 관계를 정의하고 구체적 구현에 해당하는 부분은 분리해서 정의하는 것입니다.

 

 가교 패턴에서는 추상적 개념에 대해서 기반 클래스와 파생 클래스를 제공하면서 동시에 구체적 구현에 대해서도 기반 클래스와 파생 클래스를 제공하는 형태를 지니게 됩니다. 그리고 추상적 개념을 표현한 클래스의 멤버로 구체적 구현을 한 개체를 포함하게 구현을 합니다. 그리고 추상적 개념을 표현한 클래스의 인터페이스에서는 포함하고 있는 구체적 구현된 개체를 이용하는 구조를 지니게 됩니다. 이를 통해 추상적 개념과 구체적 구현 사이에 종속성이 제거되어 다양한 구현 방법을 사용할 수 있게 해 줍니다.

 

 

 

 

 

 

 

7. 2 시나리오

 

 오늘은 아들 혁재와 함께 카메라와 렌즈를 정비하였습니다. 아들은 표면에 있는 먼지를 제거하는 작업을 하고 저는 내부에 들어간 먼지를 없애는 작업을 하였죠. 작업하는 도중에 혁재가 렌즈에 박혀 있는 레이블들을 보면서 AF, MF가 무엇인지를 묻더군요. 저는 얼른 자동 초점이 지원되는 렌즈인지 수동 초점 조절을 하는 렌즈인지를 나타내는 것이라고 얘기를 해 주었습니다. 그리고 다시 작업하는데 혁재가 다시 VR PC가 무엇인지를 묻네요. 저는 흐뭇한 표정을 지우며 자동 손 떨림 기능과 원근감 조절 기능을 제공해 주는 것이라고 대답을 해 주었죠. 저의 대답을 듣고는 혁재는 고개를 갸우뚱하더니 다시 질문합니다.

 

 "아빠, 그럼 렌즈에는 자동 초점이 되는 렌즈와 수동 초점이 되는 렌즈가 있다고 얘기를 했잖아. 그러면, 자동 초점이 되는 렌즈에는 VR 기능이 제공되는 렌즈와 PC 기능이 제공되는 렌즈, VR 기능과 PC 기능 모두 제공되는 렌즈가 있겠네. , 수동 초점이 되는 렌즈에도 VR 기능이 제공되는 렌즈, PC 기능이 제공되는 렌즈, VR 기능과 PC기능 모두 제공되는 렌즈가 있을 테고. 그리고 그 외에도 매우 많은 알파벳들이 있던데 그렇게 많은 종류의 렌즈를 생산하려면 매우 많은 생산 설비가 필요한데 지난번에 EH Camera 회사에 갔을 때는 그렇게 많지는 않았던 것 같은데."

 ". EHCamera 회사의 렌즈 생산 설비는 AF 렌즈 생산 설비와 MF 렌즈 생산 설비가 있단다. 그리고 기능별로 VR, PC 등의 모듈을 만드는 곳이 있단다. AF 렌즈에 VR 모듈을 탑재하면 AF VR 렌즈가 되고 MF 렌즈에 VR 모듈을 탑재하면 MF VR 렌즈가 된단다."

 

 혁재는 나의 대답도 끝나기 전에 정비 작업을 마치고 자신의 노트북을 향해 달려가네요.


가교 패턴



AboutBridge.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;

 

//Module.h

#pragma once

#include "common.h"

 

class Module

{

public:

             virtual string ImageProcessing(string subject)=0;

 

};

 

//PCModule.h

#pragma once

#include "Module.h"

 

class PCModule :

             public Module

{

public:

             virtual string ImageProcessing(string subject)

             {           

                           int index=-1;                     

                           while((index = subject.find("0",index+1))!=-1)

                           {

                                        subject.replace(index,strlen("0"),"1");                              

                           }

                           return subject;

             }

};

 

//VRModule.h

#pragma once

#include "Module.h"

 

class VRModule :

             public Module

{

public:

             virtual string ImageProcessing(string subject)

             {

                           int index=-1;                     

                           while((index = subject.find("떨림",index+1))!=-1)

                           {

                                        subject.replace(index,strlen("떨림"),"");

                           }

                           return subject;

             }

};

 

//Lens.h

#pragma once

 

#include "Module.h"

 

typedef vector<Module *> MVector;

typedef vector<Module *>::iterator MIter;

class Lens

{

             int focuslevel;

             static const int min_focuslevel;

             static const int max_focuslevel;

             MVector modules;              

             int mindex;

public:

             Lens(void);           

             virtual string Take(string subject,int distance)=0;

             virtual void FocusUp();

             virtual void FocusDown();

             int GetFocusLevel()const;

             void AddModule(Module *module);    

             void SetModuleIndex(int index);

             int GetModuleCount()const; 

protected:

             int GetModuleIndex()const;

             string ImageProcessing(string subject,int index); 

             string MakePicture(string subject,int distance);   

};

 

//Lens.cpp

#include "Lens.h"

 

const int Lens::min_focuslevel=1;

const int Lens::max_focuslevel=3;

Lens::Lens(void)

{

             focuslevel = min_focuslevel; 

             mindex = -1;

}

 

 

void Lens::FocusUp()

{

             if(focuslevel < max_focuslevel)

             {

                           focuslevel++;

             }

}

void Lens::FocusDown()

{

             if(focuslevel > min_focuslevel)

             {

                           focuslevel--;

             }

}

int Lens::GetFocusLevel()const

{

             return focuslevel;

}

void Lens::AddModule(Module *module)

{

             modules.push_back(module);

}

int Lens::GetModuleCount()const

{

             return modules.size();

}

 

int Lens::GetModuleIndex()const

{

             return mindex;

}

string Lens::ImageProcessing(string subject,int index)

{

             if((index>=0)||(index<GetModuleCount()))

             {

                           Module *module = modules[index];

                           subject = module->ImageProcessing(subject);

             }                                      

             return subject;

}

string Lens::MakePicture(string subject,int distance)

{

             char buf[256];

             string s = itoa(distance,buf,256);

             int index=-1;                      

             while((index = subject.find(s,index+1))!=-1)

             {

                           subject.replace(index,s.size(),"선명");                              

             }

             return subject;

}

void Lens::SetModuleIndex(int index)

{

             mindex = index;

}

 

//AFLens.h

#pragma once

#include "Lens.h"

 

class AFLens:

             public Lens

{

public:

             virtual string Take(string subject,int distance);

private:

             void AutoFocusing(int distance);

             string Processing(string subject);

};

 

//AFLens.cpp

#include "AFLens.h"

 

string AFLens::Take(string subject,int distance)

{

             AutoFocusing(distance);

             subject = Processing(subject);

             return MakePicture(subject,distance);

}

void AFLens::AutoFocusing(int distance)

{

             while(distance>GetFocusLevel())

             {

                           FocusUp();

             }

             while(distance<GetFocusLevel())

             {

                           FocusDown();

             }

}

 

string AFLens::Processing(string subject)

{           

             int mcount = GetModuleCount();

            

             for(int i =0; i<mcount; i++)

             {                         

                           subject = ImageProcessing(subject,i);                

             }

             return subject;

}

 

//MFLens.h

#pragma once

#include "Lens.h"

 

class MFLens:

             public Lens

{

public:

             virtual string Take(string subject,int distance);

             virtual void FocusUp();

             virtual void FocusDown();

};

 

//MFLens.cpp

#include "MFLens.h"

 

 

string MFLens::Take(string subject,int distance)

{                                      

             int mindex = GetModuleIndex();

            

             int mcount = GetModuleCount();

            

             if((mindex>=0)&&(mindex<mcount))

             {                         

                           subject = ImageProcessing(subject,mindex);                    

             }           

 

             return MakePicture(subject,GetFocusLevel());      

}

void MFLens::FocusUp()

{

             Lens::FocusUp();

             cout<<"현재 FocusLevel:"<<GetFocusLevel()<<endl;

}

void MFLens::FocusDown()

{

             Lens::FocusDown();

             cout<<"현재 FocusLevel:"<<GetFocusLevel()<<endl;

}

 

//Camera.h

#pragma once

 

#include "Lens.h"

class Camera

{

             Lens *lens;

public:

             Camera(void);

             void PutInLens(Lens *_lens);

             void TakeAPicture(string subject,int distance);    

             void FocusUp();

             void FocusDown();

             void SetModuleIndex(int index);

             int GetModuleCount()const; 

};

 

//Camera.cpp

#include "Camera.h"

 

Camera::Camera(void)

{

             lens = 0;

}

 

void Camera::PutInLens(Lens *_lens)

{

             lens = _lens;

}

void Camera::TakeAPicture(string subject,int distance)

{

             cout<<"피사체:"<<subject<<endl;

             if(lens==0)

             {

                           cout<<"사진:"<<"■"<<endl;

             }

            

             cout<<"사진:"<<lens->Take(subject,distance)<<endl;

}

void Camera::FocusUp()

{

             if(lens!=0)

             {

                           lens->FocusUp();

             }

}

void Camera::FocusDown()

{

             if(lens!=0)

             {

                           lens->FocusDown();

             }

}

void Camera::SetModuleIndex(int index)

{

             if(lens!=0)

             {

                           return lens->SetModuleIndex(index);

             }

}

int Camera::GetModuleCount()const

{

             if(lens!=0)

             {

                           return lens->GetModuleCount();

             }

             return -1;

}

 

//Demo.cpp

#include "common.h"

#include "Camera.h"

#include "AFLens.h"

#include "MFLens.h"

#include "PCModule.h"

#include "VRModule.h"

 

 

 

void TestAFVRPCLens(Camera *camera);

void TestMFVRLens(Camera *camera);

int main()

{           

             Camera *camera = new Camera();

 

             TestAFVRPCLens(camera);    

             TestMFVRLens(camera);       

             delete camera;

             return 0;

}

 

 

 

void TestAFVRPCLens(Camera *camera)

{

             cout<<"AFVRPCLens 테스트"<<endl;

             VRModule *vr = new VRModule();

             PCModule *pc = new PCModule();

             Lens *lens = new AFLens();

             lens->AddModule(vr);

             lens->AddModule(pc);

             camera->PutInLens(lens);

             camera->TakeAPicture("잎사귀떨림(0) 사람떨림(1) 건물(2) (3)",1);

             delete vr;

             delete pc;

             delete lens;

}

 

void TestMFVRLens(Camera *camera)

{

             cout<<"MFVRLens 테스트"<<endl;

             Module *module = new VRModule();

             Lens *lens = new MFLens();

             lens->AddModule(module);

             camera->PutInLens(lens);

             camera->TakeAPicture("잎사귀떨림(0) 사람떨림(1) 건물(2) (3)",1);

             camera->FocusUp();

             camera->TakeAPicture("잎사귀떨림(0) 사람떨림(1) 건물(2) (3)",1);

             camera->FocusDown();

             camera->SetModuleIndex(0);

             camera->TakeAPicture("잎사귀떨림(0) 사람떨림(1) 건물(2) (3)",1);

             delete module;

             delete lens;

}

 

 

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


 


반응형