프로그래머들이 프로젝트를 하면서 자주 사용되는 몇가지 유용한 프로그램 스타일 들에 이름을 붙여서 분류한 것이다. 싱글톤, 팩토리, 옵저버, 커맨드, 상태 패턴 등이 있다. 각 패턴들이 어떤 상황에서 사용되는지를 아는 것이 중요하다.
싱글톤 패턴의 특징
-싱글톤은 매니저 역할을 하는 패턴이다.
-단 하나만 존재하는 전역 클래스이다.
-함수와 변수를 static으로 선언하여 사용한다.
<cStudentMgr.h>
#pragma once
class cStudentMgr
{
private:
static cStudentMgr* m_pInstance;
int m_nID;
public:
static cStudentMgr* GetInstance(void);
void Destory(void);
inline void SetID(int nID)
{
m_nID = nID;
}
inline int GetID(void) const
{
return m_nID;
}
private:
cStudentMgr(void);
~cStudentMgr(void);
};
위 코드를 보면 생성자와 소멸자가 private 영역에 들어가 있다.
이런 경우 클래스의 객체를 만들면 생성자와 소멸자가 private이므로 호출할 수 없다는 에러가 발생한다.
생성자와 소멸자 대신에 GetInstance(), Distroy()를 사용해 프로젝트를 통틀어 단 하나의 객체만을 생성한다.
두 함수의 내부 구현은 이렇다.
<cStudentMgr.cpp>
#include "cStudentMgr.h"
///< 정적 초기화
cStudentMgr* cStudentMgr::m_pInstance = 0;
cStudentMgr::cStudentMgr(void)
:m_nID(0)
{
}
cStudentMgr::~cStudentMgr(void)
{
}
///< 싱글톤 인스턴스 포인터 얻기
cStudentMgr* cStudentMgr::GetInstance(void)
{
///< 처음 이라면
if( m_pInstance == 0 )
{
m_pInstance = new cStudentMgr;
}
return m_pInstance;
}
///< 생성된 static 인스턴스 삭제
void cStudentMgr::Destory(void)
{
if( m_pInstance != 0 )
{
delete m_pInstance;
m_pInstance = 0;
}
}
가장 위는 정적변수의 초기화이다.
생성자와 소멸자보다 위의 정적영역에서 초기화되고 있다.
(참고로 생성자에서 강조된 부분은 멤버 이니셜라이저라고 하는데, const 나 레퍼런스 변수처럼 선언과 동시에 초기화되어야 하는 변수들을 클래스에서 초기화해주는 방법이다. 여기서는 굳이 사용할 이유는 없지만 그냥 사용하고 있다-ㅅ-; 또한 상속시에 부모 생성자에 인자를 넘길때도 사용된다.)
그리고 아래 2개의 함수는 단 하나의 객체만을 생성 & 소멸시키는 기능을 하고 있다.
메인함수에서는 아래와 같이 사용된다.
#define ST_MGR cStudentMgr::GetInstance() /// 사용하기 편리하도록
int main(void)
{
ST_MGR->SetID(1);
cout << ST_MGR->GetID() << endl;
ST_MGR->Destory();
return 0;
}
싱글톤패턴은 프로젝트에 단 하나뿐인 전역 클래스로서 주로 관리자 역할을 하는 클래스를 만들어 사용하는 방식이다.
static 이므로 객체 생성없이 정적 영역의 멤버변수와 함수를 어디서나 호출하여 사용할 수 있다.
특징은 전역변수와 마찬가지로 사용하기엔 편리하지만 남용할 경우 유지보수, 가독성, 재사용성 등에 문제가 발생한다.
따라서 프로젝트당 단 하나의 클래스만 전역으로 만드는 것이 좋으며, 프로젝트 팀장의 성향에 따라 싱글톤을 아예 못쓰게 하는 경우도 있다고 한다.
※ 참고: 정적(static) 함수란?
개념적으로는 정적 멤버변수만을 접근 가능한 함수이다.
클래스가 인스턴스되지 않아도 사용가능하다.
내부적으로는 다른 멤버함수와 달리 this 포인터를 넘기지 않는다.
때문에 c에서 callback으로 넘길때 유용하다(이건 아직 무슨 말인지 모르겠다).
this 포인터가 없으므로 상속해서 오버라이딩 불가능.
또한 c에서는 하나의 파일에서만 해당 함수를 사용하고 싶을때 static을 붙인다.
댓글 없음:
댓글 쓰기