본문 바로가기
DesignPattern

[Design Pattern] Singleton Pattern

by 봄석 2019. 9. 10.

[Design Pattern] Singleton Pattern

singleton pattern에 대하여 알아보도록 하겠습니다.

 

 

싱글톤이란??

싱글톤은 단 하나의 인스턴스만 생성하도록 제약을 둔 디자인 패턴입니다.

 

싱글톤 (Singleton) 은 애플리케이션의 시작부터 종료될 때까지 

한 번의 생성(new)으로 고정된 메모리 영역을 가지기 때문에 

메모리를 효율적으로 사용할 수 있습니다.

또한 싱글톤의 인스턴스는  전역적으로 사용되기 때문에 다른 클래스의 인스턴스들이 

데이터를 공유 변경이 가능하다는 장점이 있습니다.

 

 

 

JAVA에서 구현하기

1. Eager Initialization (이른 초기화)

싱글톤 객체를 instance라는 변수로 미리 생성해 놓고 사용하는 방식입니다.

장점 : static으로 생성된 변수에 싱글톤 객체를 선언했기 때문에 클래스 로더에 의해 클래스가 로딩될 때 싱글톤 객체가 생성됩니다. 또 클래스 로더에 의해 클래스가 최초 로딩 될 때 객체가 생성됨으로 Thread-safe 합니다.

 

단점 : 싱글톤 객체를 사용하든 안 하든 해당 클래스가 로딩되는 시점에 항상 싱글톤 객체가 생성(new) 되고 메모리를 차지하고 있으니 비효율적인 방법이 될 수 있습니다.

 

2.  Lazy Initialization (늦은 초기화 방식)

 장점 : 싱글톤 객체가 필요할 때 인스턴스를 얻을 수 있습니다.  (Eager initialization 방식에 단점을 보완)

 단점 : multi-thread 환경에서 여러 곳에서 동시에 getInstance()를 호출할 경우 인스턴스가 두 번 생성될 여지가 있습니다. (동기화 문제) 

때문에  synchronized 키워드를 붙여주었습니다. 여러 thread 가 getInstance를 호출하게 되면 높은 cost 비용으로 인해 프로그램 전반에 성능 저하가 발생하는 단점이 있습니다.

 

3.  Initialization on demand holder idiom (holder에 의한 초기화 방식)

클래스 안에 클래스(Holder)를 두어 JVM의 Class Loader 메커니즘과 Class가 로드되는 시점을 이용한 방식입니다.

Lazy initialization 장점을 가져가면서 Thread 간 동기화 문제를 동시에 해결한 방법입니다.

 

SingletonByIdiom 클래스는 클래스 로드 시점에 초기화되지만 정적 클래스로 정의된

내부 클래스의 초기화는 해당 시점에 이뤄지지 않는 특성이 있습니다.

 

즉 getInstance를 통해 내부 클래스의 instance를 호출할 때 뒤늦게 초기화되어 객체를 할당한다.

이 방식이 thread safe 한 이유는 jvm의 클래스 초기화 과정에서 보장되는 원자적 특성(시리얼 하게 동작)을 이용하기 때문이다. 즉 동기화 문제를 jvm이 처리하도록 합니다.

(가장 많이 사용되고 있다고 합니다.) 

 

 

4. Enum Initialization (Enum 초기화 방식)

모든 Enum type은 프로그램 내에서 한번 초기화되는 점을 이용하는 방식입니다.

 

싱글톤의 특징(단 한 번의 인스턴스 호출, Thread간 동기화) 을 가지며 비교적 간편하게 사용할 수 있는 방법입니다.

단 한번의 인스턴스 생성을 보장하며 사용이 간편하고 직렬 화가 자동으로 처리되고 직렬화가 아무리 복잡하게 이루어져도 여러 객체가 생길 일이 없으며, 리플렉션을 통해 싱글턴을 깨트릴 수도 없다고 합니다.

(Joshua Bloch가 작성한 effective java 책에서 소개되었다고 합니다.)

 

 

Kotlin에서 구현하기

자바에서는 싱글톤 패턴을 만족하는 클래스를 작성하기 위해 몇 가지 작업이 추가적으로 필요하지만, 코틀린에선 오브젝트를(object)를object 사용하여 이를 간편하게 선언할 수 있습니다.

 

1. object keyword를 사용한 싱글톤

object SingletonObject 

자바에선 정적 변수(Static)로 구현하던 싱글톤이 코틀린에선 정적 변수가 없어지면서 , 등장한 게 Object 개념입니다.

오브젝트는 클래스를 정의하면서 동시에 인스턴스를 생성합니다.

코틀린에는 static 이 없고, 대신 이를 최상위 함수로 처리합니다

그러나 최상위 함수는 말 그대로 최상위에 존재하는 함수이기 때문에

어떤 클래스의 private 에는 당연히 접근할 수 없어 클래스 내부에 선언된 static 이 클래스의 다른 멤버와

상호 작용하는 경우를 커버할 수 없습니다.

이렇게 static 을 최상위 함수로 대체할 수 없을 때 object 를 고려한다.

object를 사용하면 자바로 변환 시 static 으로static으로 컴파일됩니다.

즉, 객체(Object)는클래스 선언과 그 클래스에 속한 단일 인스턴스의 생성을 동시에 처리해주기 때문에 싱글톤에 사용하기 적합합니다.

 

 double-checked locking 같은 locking 알고리즘에 의존하는 것 없이 thread-safe 하고 lazy 한 초기화를 가능하게 해 주기 때문에 JVM에서 싱글톤을 구현하는 방법으로 선호됩니다. 코틀린에서 간단하게 object를 선언하면, 안전하고 효율적인 싱글톤 구현을 보장받을 수 있습니다.

 

 

2. 동반 객체(compaion object)를 사용한 싱글톤

 

 

 

 


 

*Sample 보러 가기 

https://github.com/qjatjr1108/DesignPattern

 

qjatjr1108/DesignPattern

DesignPattern Sample. Contribute to qjatjr1108/DesignPattern development by creating an account on GitHub.

github.com

 

댓글