본문 바로가기
안드로이드 프로그래밍/design pattern

[kotlin] 싱글톤 패턴(Singleton pattern)에 대하여

by 1chanhue1 2024. 7. 14.

싱글톤 패턴 

  • 어떤 클래스의 인스턴스는 오직 1개임을 보장, 이 인스턴스는 전역에서 접근할 수 있는 디자인 패턴이다.
  • 어플리케이션의 시작부터 종료까지 1번의 생성으로 고정된 영역 메모리를 가지므로, 메모리를 효율적으로 사용할 수 있다

싱글톤 패턴 사용 이유

  • 프로그램에서 키보드 객체를 무한하게 제작한다면? → 입력순서가 꼬임
  • 안 될건 없지만, 중복된 동작을 하는 객체를 그 때마다 생성시키면 메모리가 낭비
  • 보통 객체는 자원이 가능한 만큼 생성할 수 있고, 각각의 객체는 상이한 위치정보/고유한 저장값을 지님
  • 싱글턴을 활용하면 해당 객체는 메모리 전역에서 유일함을 보장하고 위치정보가 고정
  • 프로그램이 실행되는 시점에 메모리에 바로 로드해서 위치를 잡음
  • 객체 자원간의 충돌 방지, 전역적으로 활용하여 다른 클래스들에서 쉽게 접근, 효율적인 메모리 활용

 

장점 

싱글톤 패턴으로 생성된 인스턴스는 오직 한개만 생성되니 고정된 메모리 영역을 사용하기 때문에 해당 인스턴스에 접근할 때 

메모리 낭비를 방지할 수 있고 이미 생성된 인스턴스를 활용하니 속도 측면에서도 이점

가장 큰 장점은 앱의 다른 화면 또는 클래스간에 데이터 공유가 쉽다는 점, 싱글톤 인스턴스가 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근하여 사용할 수 있기 때문

단점 

가장 중요한 것은 싱글톤 패턴은 하나만 생성되어야 하지만, 단일 스레드가 아닌 멀티 스레드에서 생성하는 경우, 실제로 클래스의 인스턴스가 1개만 생성된다는 것을 보장할 없다는 점이다.

 

 

 

 

 

개발을 하다보면 객체에 대한 하나의 인스턴스만 필요할 때, 하나의 인스턴스를 재사용하기 위해 싱글톤 패턴을 구현해야 할 일이 생긴다!!

다음 그럼 코틀린의 object 키워드를 사용하여 싱글톤 패턴을 적용시켜 보자 

object 키워드를 이용한 싱글톤 패턴

코틀린에서는 이를 하나의 키워드로 구현한다. 바로 object 키워드이다. 싱글톤으로 구현되어야 하는 클래스를 object 키워드를 사용함으로써 싱글톤으로 구현할 있다.

object SingletonClass {


}

SingletonObject는 한 번만 생성되는 클래스의 인스턴스로 내부의 모든 값들 역시 한 번만 생성된다.

예를 들어 다음과 같이 SampleClass의 인스턴스를 object내에서 생성했다고 해보자.

object SingletonClass {
    val sampleString = "Sample String"
}

 

여기서 sampleString는 한 번만 생성된다. 따라서 SingletonObject.sample 은 어디서나 같은 인스턴스가 된다. 

object SingletonClass {
    val sampleString = "Sample String"
}

fun main() {
    if (SingletonObject.sampleString == SingletonObject.sampleString)
        println("true")

    if (SingletonObject.sampleString === SingletonObject.sampleString)
        println("ture")
}



//출력 결과 
//true
//true

 

object를 사용할 때의 문제점

object를 사용하면 해당 객체의 초기화가 object 객체에 처음 접근될 때 이루어진다. 그 말은 내부의 모든 변수들이 초기화 된다는 뜻이다.

예를 들어 아래 SingletonClass는 firstValue에 접근하면 SingletonClass가 초기화 되기 때문에 secondValue도 초기화된다.

object SingletonClass {
    val firstValue = "first"
    val secondValue = "second"
}

 

해결책:내부 변수들의 초기화 시점 조정

object 자체가 접근 시 메모리에 곧바로 올라가는 것은 막지 못하지만, 내부 변수들을 by lazy를 이용해 생성함으로써 호출될 때 초기화를 지연 될 수 있게 만들 수 있다.

아래와 같이 object 내부의 변수값을 by lazy를 통해 지연 생성(호출될 때 메모리 상에 올라가도록 하는 방법)을 하도록 만들면 된다.

object SingletonClass {
    val firstValue = "first"
    val lazyValue by lazy { "lazy" }
}

그렇게 한다면 lazyValue는 호출될 때 처음 메모리 상에 올라가도록 할 수 있다.

이 방법을 통해 SingletonClass 내부에 많은 변수가 있을 때 메모리를 많이 잡아먹는 변수들을 지연생성을 하도록 함으로써 메모리를 최적화할 수 있다.

출처: https://kotlinworld.com/166 [조세영의 Kotlin World:티스토리]

 

 

 

'안드로이드 프로그래밍 > design pattern' 카테고리의 다른 글

[kotlin] Strategy Pattern 이란  (0) 2024.07.16