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

5. 단일체 패턴(Singleton Pattern) [Escort GoF의 디자인 패턴]

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

5. 단일체 패턴(Singleton Pattern)

 

5.1 개요

 

 단일체 패턴은 프로그램에서 특정 형식의 개체가 유일함을 보장하는 패턴을 말합니다. 일반적으로 데이터들을 관리하고 운용하는 개체를 하나만 두어 관리의 집중화를 통해 유지 보수 비용을 줄이고 높은 신뢰성을 부여할 수 있게 됩니다.

 

 사용자와 상호작용을 하는 프로그램을 작성할 때 단일체 패턴은 유용하게 사용될 수 있습니다. 사용자와 상호 작용을 담당하는 개체는 주요 데이터를 관리하는 단일 개체에게 사용자의 명령을 전달하는 역할을 합니다. 그리고 사용자에게 보여줄 정보들도 단일 개체를 통해 얻어오게 프로그래밍을 할 수 있습니다. 이처럼 프로그래밍하면 사용자와 상호 작용하는 부분을 목적에 따라 다양한 형태의 뷰를 제작할 수 있습니다. 또한, 필요에 따라서 손쉽게 뷰를 변형할 수도 있을 것입니다. 이처럼 관리되는 데이터와 데이터에 대한 제어, 사용자와 상호 작용의 결합성을 느슨하게 하면 요구 사항이 변하더라도 유연하게 대처할 수 있게 됩니다.

 

5. 2 시나리오

 

 가족과 함께 거제도에서 배로 10여 분 거리에 있는 외도를 다녀왔습니다. 여행 도중에 혁재가 카메라의 다양한 메뉴들을 살펴보다가 언어 설정을 중국어로 선택하여 잠시 혼란이 있었습니다.

 

 "아빠, 카메라가 이상해요. 글자가 깨져서 메뉴를 사용할 수가 없어요."

 

 물론, 카메라 언어 설정을 한글로 바꿔주었죠. 아들에게는 카메라를 사용하는 사람이 어떠한 언어로 사용하든지 상관없이 사용할 수 있게 언어 설정 기능이 있다는 얘기를 해 주었습니다.

 

 "카메라를 보면 매우 많은 정보들을 관리하고 사용자에게 필요한 정보를 보여주고 있지. 카메라처럼 사용자에 의해 다양한 기능이 선택되고 목적에 맞는 정보를 어떻게 보여줄 수 있는지 얘기해줄게. 카메라에는 사용자가 명령을 내릴 수 있는 장치들이 있잖아. 이 장치들이 직접적으로 필요한 정보를 생성하고 관리를 한다면 똑같은 정보가 너무 많이 생기게 되고 각 장치가 복잡하게 연결되어 있어야겠지. 이를 단순하게 하기 위해 정보를 관리하는 장치는 하나만 들어 있단다. 사용자가 명령을 내리면 그 명령이 무엇이든 상관없이 유일한 정보 관리 장치에 사용자의 명령을 전달하고 필요한 정보를 얻어와서 사용자에게 전달한단다."

 

 아들은 묻지도 않은 것에 대해 길게 설명하는 나를 이상한 눈으로 보더니 외도의 아름다운 경치로 관심을 바꾸더군요. 그래도 저는 간만에 제가 아들에게 설명할 수 있는 게 있다는 것이 아주 좋았어요.


단일체 패턴



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

 

//MemoryCard.h

#pragma once

#include "common.h"

typedef vector<string> Pictures;

class MemoryCard

{           

             Pictures pictures;

public:   

             int Store(string picture);

             int GetPictureCnt()const;

             string GetPicture(int pnum);

};

 

//MemoryCard.cpp

#include "MemoryCard.h"

 

int MemoryCard::Store(string picture)

{

             pictures.push_back(picture);

             return pictures.size();

}

int MemoryCard::GetPictureCnt()const

{

             return pictures.size();

}

string MemoryCard::GetPicture(int pnum)

{

             if( (pnum<0) || (pnum>GetPictureCnt()))

             {

                           return "";

             }

             return pictures[pnum-1];

}

 

//InterObject.h

#pragma once

#include "MemoryCard.h"

#include "common.h"

class InterObject

{

             static InterObject singleton;  

             MemoryCard *memorycard;

             int now;

public:

             static InterObject *GetSingleton();

             void PutMemoryCard(MemoryCard *_memorycard);

             void StorePicture(string subject);

             string GetPicture(); 

             void MoveBefore();

             void MoveNext();

             int GetPictureCnt();

             int GetNow();

private:

             InterObject(void);

             ~InterObject(void);

};

 

//InterObject.cpp

#include "InterObject.h"

 

InterObject InterObject::singleton;

InterObject *InterObject::GetSingleton()

{

             return &singleton;

}

 

InterObject::InterObject(void)

{           

             memorycard = 0;

             now = 0;

}

 

InterObject::~InterObject(void)

{

}

 

void InterObject::PutMemoryCard(MemoryCard *_memorycard)

{

             memorycard = _memorycard;

}

void InterObject::StorePicture(string subject)

{

             now = memorycard->Store(subject);   

}

string InterObject::GetPicture()

{                         

             return memorycard->GetPicture(now); 

}

 

void InterObject::MoveBefore()

{

             if(now>1)

             {

                           now--;

             }           

}

void InterObject::MoveNext()

{

             int cnt = memorycard->GetPictureCnt();

             if(now < cnt)

             {

                           now++;

             }           

}

 

 

int InterObject::GetPictureCnt()

{

             return memorycard->GetPictureCnt();

}

int InterObject::GetNow()

{

             return now;

}

 

//Display.h

#pragma once

 

#include "InterObject.h"

class Display

{

public:   

             virtual void View()=0;

};

 

//InfoDisplay.h

#pragma once

#include "Display.h"

 

class InfoDisplay :

             public Display

{

public:

             virtual void View()

             {

                           InterObject *interobj = InterObject::GetSingleton();

                           cout<<"정보 보기 모드"<<endl;

                           cout<<"전체 사진 :"<<interobj->GetPictureCnt()<<endl;

                           cout<<"현재 위치:"<<interobj->GetNow()<<endl;

             }

};

 

//PictureDisplay.h

#pragma once

#include "display.h"

 

class PictureDisplay :

             public Display

{

public:

             virtual void View()

             {                         

                           InterObject *interobj = InterObject::GetSingleton();

                           cout<<"사진 보기 모드"<<endl;

                           cout<<interobj->GetPicture()<<endl;                

             }           

};

 

//Camera.h

#pragma once

 

#include "common.h"

#include "InterObject.h"

#include "Display.h"

enum DisplayMode

{

             MODE_PICTURE,

             MODE_INFO         

};

 

class Camera

{

             static Camera *singleton;

 

             InterObject *interobj;                        

             Display *displayes[MODE_INFO+1];

             DisplayMode displaymode;                

public:

             static const DisplayMode mode_info;

             static const DisplayMode mode_picture;

             static Camera *GetSingleton();            

             static void Dispose();

             void PutMemoryCard(MemoryCard *_memorycard);

             void TakeAPicture(string subject);

             void View()const;  

             void BeforePicture();

             void NextPicture();

             void SetDisplayMode(DisplayMode _displaymode);

private:

             Camera(void);       

};

 

//Camera.cpp

#include "Camera.h"

#include "InfoDisplay.h"

#include "PictureDisplay.h"

 

Camera *Camera::singleton;

const DisplayMode Camera::mode_info = MODE_INFO;

const DisplayMode Camera::mode_picture = MODE_PICTURE;

Camera *Camera::GetSingleton()

{

             if(singleton==0)

             {

                           singleton = new Camera();

             }

             return singleton;

}

void Camera::Dispose()

{

             if(singleton!=0)

             {

                           delete singleton;

                           singleton=0;

             }

}

Camera::Camera(void)

{           

             interobj = InterObject::GetSingleton();

             displaymode = mode_picture;

             displayes[MODE_INFO] = new InfoDisplay();

             displayes[MODE_PICTURE] = new PictureDisplay();

}

 

void Camera::PutMemoryCard(MemoryCard *_memorycard)

{

             interobj->PutMemoryCard(_memorycard);         

}

void Camera::TakeAPicture(string subject)

{           

             interobj->StorePicture(subject);

}

void Camera::View()const

{

             displayes[displaymode]->View();         

}

 

void Camera::BeforePicture()

{

             interobj->MoveBefore();

}

void Camera::NextPicture()

{

             interobj->MoveNext();

}

void Camera::SetDisplayMode(DisplayMode _displaymode)

{

             displaymode = _displaymode;

}

 

//Demo.cpp

#include "Camera.h"

void ViewTest(Camera *camera);

int main()

{

             Camera *camera = Camera::GetSingleton();       

             MemoryCard *mc = new MemoryCard();

             camera->PutMemoryCard(mc);

            

             camera->TakeAPicture("홍길동");

             ViewTest(camera);

             camera->TakeAPicture("강감찬");

             ViewTest(camera);

 

             camera->BeforePicture();

             ViewTest(camera);

             camera->BeforePicture();

             ViewTest(camera); 

 

             camera->NextPicture();

             ViewTest(camera);

             camera->NextPicture();

             ViewTest(camera);

            

             delete camera;

             return 0;

}

void ViewTest(Camera *camera )

{

             camera->SetDisplayMode(Camera::mode_info);

             camera->View();

             camera->SetDisplayMode(Camera::mode_picture);

             camera->View();

}

 

 

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


 


반응형