Tech Log

[Design Pattern] 싱글톤 패턴 본문

Design Pattern

[Design Pattern] 싱글톤 패턴

yuhee kim 2022. 6. 19. 23:25

안드로이드 Room DB의 인스턴스를 생성할 때 반드시 싱글톤 패턴으로 생성했던 것 같다. 그때는 강의에서 그렇게 하라고 해서 했었는데, 다른 곳에서도 사용할 일이 있을 것 같아서 싱글톤 패턴에 대해 정리해본다.

 

1. 정의

위키백과에서는 다음과 같이 싱글톤 패턴을 정의하고 있다.

 

소프트웨어 디자인에서 싱글톤 패턴을 따르는 클래스는, 생성자가 여러 차례에 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다.

 

위 정의에서 알 수 있듯이, 싱글톤 패턴에서는 객체(인스턴스)를 메모리에 하나만 생성한다.

그리고 이 객체를 여러 스레드에서 동시에 어디에서든지 참조할 수 있도록 하는 것이다.

전역 범위에서 이 객체에 접근할 수 있도록 하면 어디에서든지 참조가 가능하다.

 

생성 패턴이 하나라서 싱글톤 패턴(Singleton Pattern)이라고 불린다.

 

2. 사용 이유

1) 메모리 자원의 낭비를 막기 위해서 사용된다.

객체를 하나만 생성하여 불필요한 메모리 자원 낭비를 막는다.

여러 개의 객체를 만들어서 메모리 낭비를 하지 않고, 하나의 객체를 공유해서 데이터를 변경할 수 있다.

 

2) 객체 로딩 시간이 줄어들어 성능이 좋아질 수 있다.

싱글톤 패턴으로 한 번 객체를 생성하고 나면 재사용하면 되므로 로딩 시간이 줄어든다.

 

3) 한 객체의 정보를 여러 객체에서 데이터를 공유해서 써야할 때 사용한다.

여러 객체에서 공유해서 사용해야 한다면, 그냥 객체를 여러 개 생성하면 안되나? 이렇게 생각할 수 있는데 그렇지 못하는 경우가 있다. 혹은 그렇게 하지 않는게 나은 경우가 있다.

DB(DataBase) Handler 클래스 객체를 생성하는 경우가 대표적이다.

DB Handler의 클래스 객체를 두 개 생성해놓았다면, 이 두 객체가 동시에 DB에 접근한다면 문제가 될 수 있다.

따라서 싱글톤 패턴으로 DB Handler 객체는 전역으로 한 번만 생성한다.

또한, 이 Handler는 여러 곳에서 참조하는 일이 많으므로 전역 객체로 생성해야 쉽게 접근이 가능하고 메모리 낭비를 막을 수 있다.

 

3. 예제

object SingletonClass { ... }

코틀린에서는 위와 같이 object 키워드 하나만으로 싱글톤 클래스를 생성할 수 있다.

멀티 스레드 환경을 고려할 필요없이 Thread-safe하게 싱글톤 코드를 작성할 수 있다.

 

object SingletonClass{ 
	val name="kim"
}
val SingletonObject = SingletonClass

그런데 위와 같이 작성하기만 하면 문제가 있다.

object로 싱글톤을 구현한 경우, 메모리 낭비가 일어날 수 있다.

 

코틀린 object의 경우 위 SingletonClass object는 프로세스가 시작될 때 객체가 바로 생성된다.

즉, SingletonClass라는 클래스가 사용되지 않는데도 메모리 상에 해당 클래스의 객체가 올라가 있게 된다.

 

따라서 SingletonClass의 내부 변수 name을 by lazy를 이용해 호출될 때 객체가 초기화될 수 있게 하는 방법을 사용한다.

object SingletonClass{ 
	val name by lazy { "kim" }
}
val SingletonObject = SingletonClass

by lazy를 통해서 SingletonClass의 name이 호출될 때 처음 메모리 상에 올라가게 된다.

이 방법으로 메모리 최적화를 할 수 있다.

 

4. 문제점

싱글톤 객체가 너무 많은 책임을 가지게 되고 많은 데이터를 보유하게 되면 클래스 간의 결합도가 너무 높아지게 된다는 단점이 있다.

또한 멀티 스레드 환경에서 싱글톤을 사용하려면 더욱 주의해야 한다.

(코틀린의 object를 사용하는 경우는 해당되지 않는 문제다)

멀티 스레드 환경에서 싱글톤 패턴을 사용할 때, 동일한 자원을 2개 이상의 스레드가 동시에 이용하려고 하는 경우가 일어날 수 있다.

Java로 싱글톤 패턴을 사용할 때는 더욱 주의를 해야할 것 같다.

 

 

싱글톤 패턴에 대해서 공부해보면서 코틀린에 대해서도 공부를 많이 해야할 것 같다는 생각이 들었다.

그리고 안드로이드를 공부하면 Java로 시작하지 않았더라도, 반드시 Java를 만나게 되는 것 같다.

다음에는 Room DB를 설명하면서 DB Handler 객체를 싱글톤으로 구현하는 내용을 작성해야 겠다.

 

참조

 

Comments