아이템 16 - 프로퍼티는 동작이 아니라 상태를 나타내야 한다

ds_chanin

·

2023. 4. 27. 00:55


코틀린의 프로퍼티는 자바의 필드와 비슷해 보이나 다른 개념이다.

var: name: String? = null
    get() = field?.toUpperCase()
    set(value) = {
        if(!value.isNullOrBlank()){
            field = value
        }
    }

위와 같이 파생 프로퍼티라 불리는 var를 사용해서 만든 프로퍼티는 위와같이 게터와 세터를 정의할 수 있다. 

이 때 field는 데이터를 저장하는 백킹(backing) 필드에 대한 레퍼런스이다. 백킹 필드는 따로 만들지 않아도 디폴트로 생성된다.

단, val를 이용한 읽기 전용 프로퍼티의 경우 생성되지 않는다.

 

프로퍼티는 필드가 필요하지 않다. 개념적으로 접근자라고 생각하면 된다.

따라서 val의 경우 getter, var의 경우 getter, setter를 나타낸다. 그러므로 인터페이스에도 프로퍼티를 정의할 수 있다.

interface Person {
    val name: String // getter
    var age: Int // getter, setter
}

프로퍼티는 필드가 아닌 접근자를 나타낸다고 했다.

많은 계산량이 필요한 행위를 자바에서 게터에 넣지 않는것 처럼 프로퍼티를 이용해 알고리즘을 나타내는 함수를 대체하는 것은 좋지 않다.

val Tree<Int>.sum: Int
    get() = when (this) {
        is Leaf -> value
        is Node -> left.sum + right.sum
    }

따라서 프로퍼티는 상태를 나타내거나 설정하기 위한 목적으로만 사용하는 것이 좋다.

다음과 같은 질문을 해보고 결정하는 것도 좋다.

  • 프로퍼티가 아닌 함수로 정의 할 때 get, set이 접두사로 붙는가?
  • 연산 비용이나 복잡도가 큰 경우인가?
  • 비즈니스 로직이 있는가?
  • 멱등성(결정적인가?)을 보장하는가?
  • 필드의 타입을 변환하여 전달하는가?
  • 게터 내부에서 상태가 변경되는 경우가 있는가?