Kotlin 싱글톤 구현과 companion object 정리

패스트 캠퍼스 실무 프로젝트로 배우는 Kotlin & Spring 강의 정리

Singleton

  • 클래스의 인스턴스를 단일 인스턴스로 제한하는 디자인 패턴

  • 구현할 때의 제약 사항

    • 직접 인스턴스화 하지 못하도록 생성자를 priavate으로 숨김
    • getInstance()라는 단일 인스턴스를 반환하는 static 메서드 제공
    • 멀티 스레드 환경에서도 안전하게 유일한 인스턴스를 반환해야 함
  • 구현 방법

    • DCL(Double Check Locking)
      • 메모리 이슈로 JVM 환경에서는 거의 사용하지 않는 방법
    • Enum 싱글톤
      • effective java에서 소개한 방법
    • 이른(eager) 초기화
    • 지연(lazy) 초기화
  • 자바에서 많이 쓰는 구현 방식

    • 이른 초기화
    public class Singleton {
      private static final Singleton INSTANCE = new Singletone();
        
      private Singletone() {}
        
      public static Singletone getInstance() {
        return INSTANCE;
      }
    }
    
    • 지연 초기화
    public class Singleton {
      private Singleton() { }
        
      public static Singleton getInstance() {
        return LazyHolder.INSTANCE;
      }
        
      private static class LazyHolder {
        private static final Singleton INSTANCE = new Singleton();
      }
    }
    
  • 코틀린에서는 object 키워드를 이용해서 생성 가능

import java.time.LocalDateTime

object DateTimeUtils {
    val now: LocalDateTime
        get() = LocalDateTime.now()

    // const 는 java의 상수와 같은 역할
    const val DEFAULT_FORMAT = "YYYY-MM-DD"

    fun isSame(a: LocalDateTime, b: LocalDateTime) : Boolean {
        return a == b
    }
}

Companion object

  • 클래스 내부에서 생성하는 객체
  • 내부에 멤버 필드, 메서드 가질 수 있음
  • 동반 객체의 이름은 보통 생략
class MyClass {
    
    companion object  {
        val a = 12345

        fun newInstance() = MyClass()
    }
}

class Test {
    companion object myCompanion {
        val b = 1
    }
}


fun main() {
    println(MyClass.newInstance())		// MyClass@2ff4acd0
    println(MyClass.Companion.a)			// 12345
    println(Test.myCompanion.b)				// 1
}