Object와 Companion object의 이해

 

 개요

 

이번 미션을 진행하면서, 위와 같은 코드 리뷰를 받게 되었습니다.

이에 대해서 아래와 같이 답변을 달게 되었는데요,

 

내가 제대로 이해하고 있는 것이 맞는지, 확인하기 위해서 Object와 Companion object의 차이에 대하여 학습하는 시간을 가졌습니다.

 

 

Object

코틀린에서는 싱글톤 패턴을 구현하기 위해서 object를 사용합니다.

object는 싱글톤 패턴을 쉽게 사용하기 위해서 코틀린에서 제공하는 객체 선언 키워드입니다.

 

object Error {
    private const val ERR_MSG = "[ERROR]"

    const val NOT_EXIST_MENU = "$ERR_MSG 존재하지 않는 메뉴 입니다."
    const val IS_INCORRECT_BENEFIT = "$ERR_MSG 올바르지 않은 혜택 금액 입니다."

    const val IS_INCORRECT_DATE = "$ERR_MSG 유효하지 않은 날짜입니다. 다시 입력해 주세요."
    const val IS_INCORRECT_ORDER = "$ERR_MSG 유효하지 않은 주문입니다. 다시 입력해 주세요."

    const val JUST_ORDER_BEVERAGE = "$ERR_MSG 음료만 주문 할 수 없습니다. 다시 입력해 주세요."
    const val OVER_MAX_MENU =
        "$ERR_MSG 메뉴는 한 번에 최대 ${Limit.MAX_MENU_AMOUNT}${Form.UNIT_OF_MENU}까지만 주문할 수 있습니다."

}

 

Object로 객체를 선언하게 되면 아래와 같은 장점을 가지게 됩니다.

 

- 오브젝트로 선언된 클래스는 thread safe라는 큰 이점이 있다.

- thread safe : 멀티 스레드 환경에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램 실행에 문제가 생기지 않는다.

- lazy initialization : 오브젝트 키워드가 선언된 클래스는 외부에서 객체가 사용되는 시점에 초기화 된다.

 

반면에 Object 클래스는 주/부 생성자를 사용할 수 없다는 특징이 있습니다.

객체 생성과 동시에 생성자 호출 없이 만들어지기 때문인데요, 클래스나 인터페이스를 상속할 수도 있습니다.

 

 

companion object

 

companion object는 클래스 내부의 객체 선언을 위한 object 키워드 입니다.

클래스 내부에서 싱글톤 패턴을 구현하기 위해서 사용하며, Object 키워드처럼 생성자 없이 호출할 수 있습니다.

 

val badge = Badge.getEventBadge(3_000)

 

companion object는 클래스 인스턴스 없이 어떤 클래스 내부에 접근하고 싶을 때 선언하며,

클래스당 하나만 사용할 수 있고 런타임시 실제 객체의 인스턴스로 실행된다는 특징이 있습니다.

 

두 싱글톤 패턴의 차이

 

Object 클래스는 클래스 전체가 하나의 싱글톤 객체로 선언되지만, companion object는 클래스 내에 일부분이 선언됩니다.

둘의 초기화 시점이 각각 사용될때 초기화, 클래스가 속한 클래스가 load될 때 초기화로 다르다는 것을 알 수 있습니다.

 

코드 리뷰에 둘의 차이에 대하여 설명할 때, 두 싱글톤 패턴의 초기화 시점을 제대로 이해하고 있었습니다.

하지만 이러한 이유가 클래스와 오브젝트로 분류하여 사용한 것이 맞는 것인지는 잘 모르겠습니다.

 

Object 클래스의 사용을 주로 레트로핏 객체를 생성할 때 싱글톤으로 사용하였으며,

companion object는 해당 클래스에서 필요한 상수를 선언할 때 사용하였습니다.

 

두 싱글톤 패턴의 초기화 시점 차이를 이해하고, 각 상황에 맞게 적용하는 것이 좋겠습니다.