소프트웨어 디자인 패턴에서 싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다. 주로 공통된 객체를 여러개 생성해서 사용하는 DBCP(DataBase Connection Pool)와 같은 상황에서 많이 사용된다. (위키백과)
싱글톤 패턴은 한 마디로 어떤 클래스의 객체가 단 하나만 생성되는 패턴
이라고 선 요약할 수 있다. 어떤 클래스의 생성자를 여러 번 호출해도 실제로 생성되어 있는 생성자는 하나이고, 이미 생성된 객체를 반환하는 식으로 사용하게끔 하는 방식을 뜻한다.
주로 공통된 객체를 여러 개 생성해서 사용하는 DBCP(Database Connection Pool)
와 같은 데이터베이스 연결 모듈에 많이 사용된다. 데이터베이스에서 데이터를 가져오는 작업은 무겁기도 하거니와 굳이 여러 개나 생성할 필요가 없이 하나를 공유해서 사용할 수 있기 때문이다.
class Singleton
{
private:
static Singleton instance;
Singleton() {}
public:
static Singleton getInstance()
{
return instance;
}
};
핵심은 기본 생성자가 private
으로 선언되어 외부에서 생성자를 호출하는 것을 막고 있다는 점이다.
전체 프로그램에서 클래스의 객체를 하나만 생성하여 사용하기 때문에 객체의 생성에 사용되는 메모리를 절약할 수 있다는 것이 가장 큰 장점이라고 할 수 있다. 그리고 객체를 매번 생성하지 않고 이미 만들어져 있는 객체를 활용하기 때문에 속도 측면에서도 우수하다.
또한, 싱글톤 객체는 전역에서 데이터를 공유하여 사용하기 용이하다는 장점이 있다. 그러나 멀티스레드 환경에서는 동일한 데이터에 여러 곳에서 하나의 객체에만 접근하므로 동시성 문제가 발생할 수 있다. 따라서 이를 예방할 수 있는 방지책이 필수적이다.
프로그램 실행 중 클래스 객체가 언제나 유일하다는 보장이 필요할 경우 싱글톤 패턴을 효과적으로 사용할 수 있다.
전역적으로 데이터를 관리하고, 곳곳에서 이를 공유할 수 있다는 점은 단점으로 작용하기도 한다. 동시에 여러 스레드에서 객체에 접근하다간 동시성 문제가 발생할 수 있고, 따라서 이를 해결하기 위한 구현이 추가로 요구된다.
만약 하나의 스레드가 객체를 사용하는 동안 다른 스레드에서 대기를 거는 방식으로 동시성 문제를 해결했다면 대기하는 시간만큼 약간의 성능 저하가 발생할 수 있다. 메모리 공간을 절약할 수 있다는 장점과 trade-off가 발생한다고 보면 될 것 같다.
클래스 객체가 유일하다는 것은 다시 말해 코드 전반에 걸쳐 그 객체의 의존성이 높다고 할 수 있다. 의존성이 높아지면 수정이나 테스트를 진행하기 까다로워진다.
한 객체에 의해 많은 데이터가 공유되면 여러 클래스들 간의 결합성이 증가하게 되어 '확장' 에 대해 개방되어 있고, '수정' 에 대해 닫혀 있어야 한다는 객체 지향 프로그래밍의 원리 (OCP, Open-Closed Principle)에 위배될 수 있다.