6. 적응자 패턴(Adapter Pattern)
6.1 개요
적응자 패턴은 서로 비슷한 기능을 하지만 사용 방법이 다른 경우 같은 인터페이스를 갖게 변환시키는 패턴입니다. 변환시키기 전에는 서로 다른 방법으로 사용해야 했던 작업들을 일관된 인터페이스를 사용할 수 있어 사용이 쉬워집니다. 적응자 패턴은 사용자에게 익숙한 인터페이스 형태로 포장하여 제공한다는 의미에서 래퍼(Wrapper)라고도 부릅니다.
6. 2 시나리오
어느 날 강의를 하고 있는데 이 매핑 씨에게 전화가 왔습니다.
"안녕하세요. 혁재 아버지!"
"네, 잘 지내시죠. 그런데 어떤 일로 저에게…"
"저희가 이번에 새로운 모듈을 개발했거든요. 그런데 개발하는 과정에서 기존 모듈과 사용 방법이 다르게 만들게 되었어요. 개발을 완료해서 보니 모듈이 H/W에 종속적인 기능이 아니라서 기존 카메라에도 적용을 시킬 수 있다는 판단을 하게 되었어요."
이 매핑 씨와 통화를 하다 보니 처음 영상 처리 모듈을 개발할 당시에는 새로운 카메라에만 적용할 목적으로 개발하였다고 하네요. 그런데 개발을 완료해서 보니 새로운 영상 처리 모듈이 H/W와 독립적인 기능이라 기존 카메라의 펌웨어 업그레이드를 통해 제공하고 싶은데 모듈 사용 방법이 기존 모듈들과 달라 다시 개발해야 할 것 같다는 얘기였습니다. 제가 전산 실무에 대해 교육을 하는 것을 알고 효과적인 방법이 있는지 자문을 요청한 것이죠.
저는 강의를 마치고 EHCamera 개발팀을 방문한 후에 기존 모듈과 새로운 모듈을 살펴보았습니다. 다행스럽게 두 개의 모듈은 노출된 기능의 이름만 서로 다르고 다른 부분은 크게 다르지 않았습니다. 간단하게 기존의 모듈에서 노출한 기능과 일치하는 인터페이스를 만들어 새로운 모듈을 감싸는 작업을 해 주고 이와 같은 구조 패턴에 대해 간략히 설명해 주었습니다.
적응자 패턴 적용 전 클래스 다이어그램 및 실행 결과
BeforeAdapter.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;
//PImageProcessor.h
#pragma once
#include "common.h"
class PImageProcessor
{
string subject;
string picture;
int index;
int oindex;
public:
PImageProcessor(void);
~PImageProcessor(void);
void SetSubject(string _subject);
void FindBegin();
bool FindNextPeople();
void ImageProcessing();
string GetPicture();
};
//PImageProcessor.cpp
#include "PImageProcessor.h"
PImageProcessor::PImageProcessor(void)
{
subject = "";
picture = "";
index = -1;
oindex = -1;
}
PImageProcessor::~PImageProcessor(void)
{
}
void PImageProcessor::SetSubject(string _subject)
{
subject = _subject;
}
void PImageProcessor::FindBegin()
{
picture = subject;
index = -1;
oindex = -1;
}
bool PImageProcessor::FindNextPeople()
{
oindex = index;
index = subject.find("people",oindex+1);
return index != -1;
}
void PImageProcessor::ImageProcessing()
{
picture.replace(index,strlen("people"),"PEOPLE");
}
string PImageProcessor::GetPicture()
{
return picture;
}
//Camera.h
#pragma once
#include "PImageProcessor.h"
class Camera
{
PImageProcessor *pi_processor;
public:
Camera(PImageProcessor *_pi_processor);
string TakeAPicture(string subject);
private:
};
//Camera.cpp
#include "Camera.h"
Camera::Camera(PImageProcessor *_pi_processor)
{
pi_processor = _pi_processor;
}
string Camera::TakeAPicture(string subject)
{
int index = 0;
string picture="";
pi_processor->SetSubject(subject);
pi_processor->FindBegin();
while(pi_processor->FindNextPeople())
{
pi_processor->ImageProcessing();
}
return pi_processor->GetPicture();
}
//Demo.cpp
#include "Camera.h"
int main()
{
PImageProcessor *pi_processor = new PImageProcessor();
Camera *ca = new Camera(pi_processor);
string picture = ca->TakeAPicture("people animal people plant");
cout<<picture<<endl;
delete ca;
delete pi_processor;
return 0;
}
적응자 패턴 적용 후 클래스 다이어그램 및 실행 결과
//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;
//ImageProcessor.h
#pragma once
#include "common.h"
class ImageProcessor
{
public:
virtual void SetSubject(string _subject)=0;
virtual void FindBegin()=0;
virtual bool FindNextPeople()=0;
virtual void ImageProcessing()=0;
virtual string GetPicture()=0;
};
//PImageProcessor.h
#pragma once
#include "ImageProcessor.h"
#include "common.h"
class PImageProcessor:
public ImageProcessor
{
string subject;
string picture;
int index;
int oindex;
public:
PImageProcessor(void);
void SetSubject(string _subject);
void FindBegin();
bool FindNextPeople();
void ImageProcessing();
string GetPicture();
};
//PImageProcessor.cpp
#include "PImageProcessor.h"
PImageProcessor::PImageProcessor(void)
{
subject = "";
picture = "";
index = -1;
oindex = -1;
}
void PImageProcessor::SetSubject(string _subject)
{
subject = _subject;
}
void PImageProcessor::FindBegin()
{
picture = subject;
index = -1;
oindex = -1;
}
bool PImageProcessor::FindNextPeople()
{
oindex = index;
index = subject.find("people",oindex+1);
return index != -1;
}
void PImageProcessor::ImageProcessing()
{
picture.replace(index,strlen("people"),"PEOPLE");
}
string PImageProcessor::GetPicture()
{
return picture;
}
//AImageProcessor.h
#pragma once
#include "common.h"
class AImageProcessor
{
string image;
string picture;
int index;
int oindex;
public:
AImageProcessor(void);
void SetOrigin(string _image);
void FindStart();
bool FindNextAnimal();
void Processing();
string GetPicture();
};
//AImageProcessor.cpp
#include "AImageProcessor.h"
AImageProcessor::AImageProcessor(void)
{
image = "";
picture = "";
index = -1;
oindex = -1;
}
void AImageProcessor::SetOrigin(string _image)
{
image = _image;
}
void AImageProcessor::FindStart()
{
picture = image;
index = -1;
oindex = -1;
}
bool AImageProcessor::FindNextAnimal()
{
oindex = index;
index = image.find("animal",oindex+1);
return index != -1;
}
void AImageProcessor::Processing()
{
picture.replace(index,strlen("animal"),"ANIMAL");
}
string AImageProcessor::GetPicture()
{
return picture;
}
//WrapAImageProcessor.h
#pragma once
#include "ImageProcessor.h"
#include "AImageProcessor.h"
class WrapAImageProcessor:
public ImageProcessor
{
AImageProcessor *ai_processor;
public:
WrapAImageProcessor();
~WrapAImageProcessor();
void SetSubject(string _subject);
void FindBegin();
bool FindNextPeople();
void ImageProcessing();
string GetPicture();
};
//WrapAImageProcessor.cpp
#include "WrapAImageProcessor.h"
WrapAImageProcessor::WrapAImageProcessor()
{
ai_processor = new AImageProcessor();
}
WrapAImageProcessor::~WrapAImageProcessor()
{
delete ai_processor;
}
void WrapAImageProcessor::SetSubject(string _subject)
{
ai_processor->SetOrigin(_subject);
}
void WrapAImageProcessor::FindBegin()
{
ai_processor->FindStart();
}
bool WrapAImageProcessor::FindNextPeople()
{
return ai_processor->FindNextAnimal();
}
void WrapAImageProcessor::ImageProcessing()
{
ai_processor->Processing();
}
string WrapAImageProcessor::GetPicture()
{
return ai_processor->GetPicture();
}
//Camera.h
#pragma once
#include "ImageProcessor.h"
class Camera
{
ImageProcessor *img_processor;
public:
Camera(ImageProcessor *_img_processor);
string TakeAPicture(string subject);
void UpgradeFirmWare(ImageProcessor *_img_processor);
private:
};
//Camera.cpp
#include "Camera.h"
#include "PImageProcessor.h"
Camera::Camera(ImageProcessor *_img_processor)
{
img_processor = _img_processor;
}
string Camera::TakeAPicture(string subject)
{
int index = 0;
string picture="";
img_processor->SetSubject(subject);
img_processor->FindBegin();
while(img_processor->FindNextPeople())
{
img_processor->ImageProcessing();
}
return img_processor->GetPicture();
}
void Camera::UpgradeFirmWare(ImageProcessor *_img_processor)
{
img_processor = _img_processor;
}
//Demo.cpp
#include "Camera.h"
#include "WrapAImageProcessor.h"
#include "PImageProcessor.h"
int main()
{
ImageProcessor *ips[2];
ips[0] = new PImageProcessor();
ips[1] = new WrapAImageProcessor();
Camera *ca = new Camera(ips[0]);
string picture = ca->TakeAPicture("people animal people plant");
cout<<picture<<endl;
ca->UpgradeFirmWare(ips[1]);
picture = ca->TakeAPicture("people animal people plant");
cout<<picture<<endl;
delete ca;
delete ips[0];
delete ips[1];
return 0;
}
|
'프로그래밍 기술 > Escort GoF의 디자인 패턴' 카테고리의 다른 글
11. 플라이급 패턴(Flyweight Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
---|---|
10. 퍼샤드 패턴(Facade Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
9. 장식자 패턴(Decorator Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
8. 복합체 패턴(Composite Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
7. 가교 패턴(Bridge Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
5. 단일체 패턴(Singleton Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
4. 원형 패턴(Prototype Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
3. 팩토리 메서드 패턴(Factory Method Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
2. 빌더 패턴(Builder Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |
1. 추상 팩토리 패턴 (Abstract Factory Pattern) [Escort GoF의 디자인 패턴] (0) | 2016.04.04 |