오직 한개의 인스턴스(객체)만을 갖도록 보장하고, 이에대한 전역적인 접근점을 제공한다.
싱글턴은 부적당한 곳에서 사용하면 총상에 부목을 대는 것만큼이나 쓸모가 없다. 워낙 남용되는 패턴이다 보니 싱글턴을 회피할수 있는 방법을 주로 다루겠다. 그전에 싱글턴에 대해서 살펴보자.
오직 한개의 인스턴스만 갖도록 보장하는 것이 싱글턴이다. 인스턴스가 여러개면 제대로 작동하지 않는 상황이 자연스럽게 늘어나게 된다. 외부 시스템과 상호작용하면서 전역상태를 관리하는 클래스 같은것이다. 파일 시스템을 관리하느 API 래핑 클래스가 있다고 하자. 작업을 완료하느데 시간이 걸리것이다. 그래서 이 클래스는 비동기로 만들어준다. 즉 여러작업을 동시에 진행할 수 있도록 서로 조율할 것이다. 한쪽에서는 파일을 생성하고 한쪽에서는 생성한 파일을 삭제하려고 하면, 래퍼 클래스가 두 작업을 다 파악해서 서로 간섭하지 못하게 해야한다.
이를 위해서 파일 시스템 클래스로 들어온 호출이 이전 작업 전체에 대해서 접근할 수 있어야 한다. 아무데서나 파일시스템 클래스 인스턴스를 만들 수 있다면 다른 인스턴스에서 어떤 작업을 진행중인지 알수 없다. 이를 싱글턴 클래스로 인스턴스를 하나만 가지도록 강제 할수 있다.
로깅, 콘텐츠 로딩, 게임 저장 등 여러 내부에서 파일 시스템 을 이용한 API를 사용할것이다. 이들 시스템에서 클래스 인스턴스를 따로 생성할수 없다면, 파일 시스템에는 어떻게 접근해야하는가?
여기에 대한 해결책을 싱글턴이 제공한다. 하나의 인스턴스만 생성해버리고 전역변수혀앹로 메서드를 제공한다면 어디에서든 호출 할수 있을 것이다.
class FileSystem
{
public:
static FileSystem& instance()
{
// Lazy initialize.
if (instance_ == NULL) instance_ = new FileSystem();
return *instance_;
}
private:
FileSystem() {}
static FileSystem* instance_;
};
instance_ 정적 멤버 변수는 클래스 인스턴스를 저장한다. 생성자가 private 이기 떄문에 외부에서는 해당 객체를 생성할수 없다. public 에있는 instance()만을 이용해서 접근이 가능하다.
최초로 한번만 객체가 생성이 되고 해당 인스턴스에 어디에서든지, 언제든지 접근이 가능한 형태를 제공해준다. (싱글턴)
class FileSystem
{
public:
static FileSystem& instance()
{
static FileSystem *instance = new FileSystem();
return *instance;
}
private:
FileSystem() {}
};