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

15. 프락시 패턴(Proxy Pattern) - 스마트 참조자 [Escort GoF의 디자인 패턴]

언제나휴일 2016. 4. 4. 14:21
반응형

15. 프락시 패턴(Proxy Pattern) - 스마트 참조자

 

15.1 개요

 

 이번에는 프락시 패턴 중에서 스마트 참조자에 대해 살펴보기로 합시다.

 

 스마트 참조자는 다른 프락시 패턴들처럼 실제 개체를 사용하는 같은 방식으로 사용할 수 있습니다. 그리고 스마트 참조자에서는 자신 내부에 실제 개체(스마트 포인터)를 포함하고 있으며 복사 생성을 할 때의 실제 개체에 참조 개수를 추가하고 소멸을 할 때에는 참조 개수를 감소시켜 참조 개수가 0이 되면 실제 개체를 소멸해 줍니다. C++ 언어에서 스마트 참조자의 경우에는 클래스 형식의 포인터 변수를 사용하지 않아도 사용자가 개체의 생성과 소멸에 관한 책임을 하지 않아도 되게 해 줍니다. 또한, 비동기 프로그래밍할 때 스마트 참조자를 통해 실제 개체에 접근할 때 동기화 처리를 해서 신뢰성을 높일 수 있습니다.

 

15. 2 시나리오

 

 지난 주말에 아산에 있는 공세리 성당에 다녀왔습니다. 제자들이 그런 곳에도 놀러 가느냐고 물었을 때 저는 수덕사에 놀러 가는 것과 다름이 없다고 얘기를 한 기억이 나네요.

 

 공세리 성당에 도착하였을 때 아들과 아내는 눈앞에 비치는 아름다움에 빠져들었죠. 이때부터 모두 서로가 카메라를 잡고 아름다운 경치를 앵글에 담겠다고 난리가 났어요. 결국, 혁재가 카메라를 차지하게 되었고 아내는 캠코더를 갖고 촬영에 들어갔지요. 저는 다행히도 갖고 갔던 박완서 님의 '가보지 않은 길이 더 아름답다.'를 볼 수 있는 영광을 누리게 되었지요.

 

 저녁에 집으로 돌아와서 카메라 제어 장치를 하나 만들었어요. 제가 만든 제어 장치는 여러 명이 한 대의 카메라를 제어할 수 있게 하는 장치예요. 이를 사용하기 위해서는 첫 번째 장치는 제어할 카메라의 정보를 입력하게 하였고 이후 사용할 장치들은 설정된 장치를 기반으로 카메라 정보를 입력되도록 하였습니다. 하지만 이게 제대로 동작할지 유용하게 사용될지는 잘 모르겠어요.


스마트 참조자 , 프락시 패턴


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

 

//ITake.h

#pragma once

#include "common.h"

class ITake

{

public:

             virtual string TakeAPicture(string subject)=0;                   

             virtual void ChangeMode(bool mode)=0;

             virtual bool GetMode()=0;

};

 

//Camera.h

#pragma once

#include "ITake.h"

class Camera

             :public ITake

{

             bool mode;

             int refcount;

public:

             Camera(void);       

             virtual string TakeAPicture(string subject);

             virtual void ChangeMode(bool mode);

             virtual bool GetMode();

             int AddRef();

             int ReleaseRef();

};

 

//Camera.cpp

#include "Camera.h"

 

Camera::Camera(void)

{

             mode = false;

             refcount=0;          

}

 

 

string Camera::TakeAPicture(string subject)

{

             cout<<"사진을 찍습니다."<<endl;

             if(mode)

             {

                           return "수동 모드로 찍힌 사진:"+subject;

             }

             return "자동모드로 찍힌 사진:"+subject;

}

void Camera::ChangeMode(bool mode)

{

            

             this->mode = mode;

             if(mode)

             {

                           cout<<"수동 모드로 변환되었습니다."<<endl;

             }

             else

             {

                           cout<<"자동 모드로 변환되었습니다."<<endl;

             }

}

bool Camera::GetMode()

{           

             if(mode)

             {

                           cout<<"수동 모드입니다."<<endl;

             }

             else

             {

                           cout<<"자동 모드입니다."<<endl;

             }

             return mode;

}

 

int Camera::AddRef()

{

             refcount++;

             cout<<"참조 카운터 증가:"<<refcount<<endl;

             return refcount;

}

int Camera::ReleaseRef()

{

             refcount--;

             cout<<"참조 카운터 감소"<<refcount<<endl;

             return refcount;

}

 

//RefCamera.h

#pragma once

#include "ITake.h"

#include "Camera.h"

class RefCamera :

             public ITake

{

             Camera *camera;

public:

             RefCamera(void);

             RefCamera(const RefCamera &refer_camera);

             ~RefCamera(void);

             virtual string TakeAPicture(string subject);                       

             virtual void ChangeMode(bool mode);

             virtual bool GetMode();

             Camera *operator->();

};

 

//RefCamera.cpp

#include "RefCamera.h"

#include "Camera.h"

RefCamera::RefCamera(void)

{

             camera = new Camera();

             camera->AddRef();

}

 

RefCamera::~RefCamera(void)

{

             if(camera->ReleaseRef()==0)

             {

                           delete camera;

             }

}

RefCamera::RefCamera(const RefCamera &refer_camera)

{

             this->camera = refer_camera.camera;

             camera->AddRef();

}

string RefCamera::TakeAPicture(string subject)

{

             return camera->TakeAPicture(subject);

}

void RefCamera::ChangeMode(bool mode)

{

             camera->ChangeMode(mode);

}

bool RefCamera::GetMode()

{

             return camera->GetMode();

}

Camera *RefCamera::operator->()

{

             return camera;

}

 

//Demo.cpp

#include "RefCamera.h"

int main()

{

             RefCamera rc1;

             RefCamera rc2(rc1);

             RefCamera rc3(rc1);

             RefCamera rc4(rc1);

 

             cout<<rc1->TakeAPicture("현충사의 ")<<endl;

             rc2->ChangeMode(true);

             cout<<rc3->TakeAPicture("현충사의 ")<<endl;

             rc4->ChangeMode(false);

             cout<<rc3->TakeAPicture("현충사의 2")<<endl;

             return 0; 

}

 

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


 

반응형