object

싱글톤 (Singleton)

object

싱글톤


객체 생성 시 단 한번 메모리에 할당하고 그 메모리에 인스턴스를 생성해서 전역적으로 접근 가능하게하는 디자인 패턴으로 Application 종료 시 해제된다.


자바의 싱글톤


자바에서 싱글톤 패턴을 구현하기 위해서는 생성자에 private 접근 제한자를 선언하고 private static 멤버 변수에 인스턴스를 저장해서 팩토리 패턴으로 캐시되어 있는 동일한 인스턴스를 반환하는 방법을 사용한다.

public class Singleton {
    private static Singleton instance; // 싱글톤 객체를 담을 static 변수
	
    // 싱글톤 객체의 생성자에 private 접근 제어자를 정의하여
    // 외부에서 싱글톤 객체의 접근을 막음
    private Singleton() {}

    // 싱글톤 객체를 담은 static 변수를 반환하는 메소드
    public static Singleton getInstance() {
        if (instance == null) { // null 이면 싱글톤 객체 생성
            // 스레드 동시 접근 시 인스턴스 여러번 생성하여 Thread-Safe 보장 안함
            instance = new Singletone();
        }
        return instance;
    }
}
public class Singleton {	
    private Singleton() { }

    public static Singleton getInstance() {
        return LazyHolder.INSTANCE;
    }

    // getInstance() 에서 LazyHolder.INSTANCE 참조하는 순간 초기화 진행
    // 클래스 초기화 시점에는 Thread-Safe 를 보장하기에 volatile, synchronized 없어도 됨
    private static class LazyHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
}



코틀린 object


코틀린에서 object 변수 선언은 클래스의 인스턴스를 생성하고 그 클래스의 속성과 함수를 오버라이딩(Overrideing) 할 수 있다.

// MouseAdapter 클래스를 인스턴스를 만들고 재정의하여 addMouseListener() 의 파라미터로 전달
window.addMouseListener(object: MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) { /* ... */ }
    override fun mouseEntered(e: MouseEvent) { /* ... */ }
})


코틀린에서 자바의 복잡한(?) 과정 없이 클래스에 object 키워드를 사용하여 객체를 생성하면 1개의 인스턴스를 가지는 싱글톤 클래스가 만들어진다.

fun main() {
    println(Obj.count)
    println(Obj.getCount())
}

object Obj {
    val count = 100

    fun getCount(): Int = count
}


// 100
// 100



companion object (동반 객체)


코틀린에서 클래스 내에 싱글톤 객체를 가지고 싶을 때 사용할 수 있다.

자바의 static 과 같으며 이름을 붙일 수 있고 객체이기 때문에 interface 구현도 가능하다.

fun main() {
    // 동반 객체의 getName() 을 통해 private 생성자에 접근 가능
    println(A.getName())
}


interface Movable {
    fun move()
}


class A private constructor(
    val name: String
) {
    companion object {
        fun getCar(): A = A("BMW")
    }
}


class B {
    companion object Obj{ }
}


class C {
    companion object: Movable {
        override fun move() {
            println("이동")
        }
    }
}


// BMW
essential