실무 프로젝트로 배우는 Kotlin & Spring/코틀린 고급

싱글톤과 동반객체

webmaster 2022. 10. 9. 17:34
728x90

싱글톤

  • 싱글톤 패턴은 클래스의 인스턴스를 하나의 단일 인스턴스로 제한하는 디자인 패턴이다.
  • 싱글톤 패턴의 제약사항
    • 직접 인스턴스화 하지 못하도록 생성자를 private로 숨긴다.
    • getInstance()라는 클래스의 단일 인스턴스를 반환하는 static 메서드를 제공한다.
    • 멀티-스레드 환경에서도 안전하게  유일한 인스턴스를 반환해야 한다.
  • 구현 방법
    • DCL(JVM환경에서는 거의 사용 안 함)
    • Enum 싱글톤(이펙티브 자바에서 소개)
    • 이른 초기화(Eager)
    • 지연 초기화(Lazy)

이른 초기화

public class Java_Singleton {
    private static final Java_Singleton INSTANCE = new Java_Singleton();
    private Java_Singleton() {
        /* do nothing */
	} 
    public Java_Singleton getInstance() {
        return INSTANCE;
	} 
}

지연 초기화

public class Java_Singleton {
    private Java_Singleton() {
        /* do nothing */
	} 
    public Java_Singleton getInstance() {
        return LazyHolder.INSTANCE;
	} 
    private static class LazyHolder {
        private static final Java_Singleton INSTANCE = new Java_Singleton();
	} 
}

 

코틀린의 싱글톤

/*
//객체 선언을 통해 싱글톤 선언
object Singleton {
    val a = 1234
    fun printA() = println(a)
}

fun main(){
    println(Singleton.a)
    Singleton.printA()
}
*/
object DateTimeUtils {
    val now: LocalDateTime
        get() = LocalDateTime.now()

    const val DEFAULT_FORMAT = "YYYY-MM-DD" //상수를 표기할 때, const 키워드를 사용한다.

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

fun main() {
    println(DateTimeUtils.now)
    println(DateTimeUtils.now)
    println(DateTimeUtils.now)
    println(DateTimeUtils.DEFAULT_FORMAT)
    val now = LocalDateTime.now()
    println(DateTimeUtils.same(now, now))
}
  • 코틀린의 object 키워드를 통해 싱글톤을 기본 지원한다.
  • 함수나 변수를 사용할 때, 클래스 한정자를 사용한다(클래스명. 함수명)
  • 객체 선언을 사용하면 자바의 static 유틸리티를 대신핸 쉽게 싱글톤 기반의 유틸리티를 만들 수 있다(DateTimeUtils)

동반 객체(클래스 내부 클래스)

//동반 객체
class MyClass {
    private constructor() //생성자를 직접 호출 못하도록 한다.

    companion object MyCompanion{
        val a = 1234
        fun newInstance() = MyClass()
    }
}

fun main() {
    println(MyClass.a)
    println(MyClass.newInstance())

    println(MyClass.MyCompanion.a) //Companion 이름을 붙여서 사용할 수 있다
    println(MyClass.MyCompanion.newInstance())
}
  • companion 키워드를 사용해 클래스 내부에 객체 선언을 사용할 수 있다.
  • 동반 객체의 멤버는 object로 선언한 객체와 마찬가지로 클래스 한정자를 사용해 호출할 수 있다.
  • 생성자를 private로 숨기고, newInstance함수를 통해서만 객체 생성을 가능하게 할 수 있다.
  • 동반 객체는 이름을 가질 수 있고, 호출 시에도 이름으로 호출해야 한다(단, 이름 지정을 하지 않았을 경우 생략이 가능하다)

 

728x90

'실무 프로젝트로 배우는 Kotlin & Spring > 코틀린 고급' 카테고리의 다른 글

제네릭  (0) 2022.10.16
확장 함수  (0) 2022.10.09
실드 클래스  (0) 2022.10.09
데이터 클래스  (0) 2022.10.08
컬렉션  (0) 2022.10.08