[Effective Kotlin] 아이템16. 프로퍼티는 동작이 아니라 상태를 나타내야 한다

Jimin Lim·2023년 7월 21일
0

Effective Kotlin

목록 보기
16/39
post-thumbnail

아이템 16

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

✅ 프로퍼티

🔗 사용자 정의 게터, 세터

코틀린의 프로퍼티, 자바의 필드는 둘 다 데이터를 저장한다는 점에서 같지만 프로퍼티는 더 많은 기능이 있다. 기본적으로 프로퍼티는 사용자 정의 세터와 게터를 가질 수 있다.

var name: String? = null
    get() = field?.toUpperCase() //배킹 레퍼런스!
    set(value) {
        if (!value.isNullOrBlack()) {
            field = value
        }
    }
  • field: 데이터를 저장해두는 배킹 필드에 대한 레퍼런스, 따로 생성하지 않아도 디폴트로 생성. val에서는 생성되지 않음
  • var을 사용해 만든 프로퍼티: 파생 프로퍼티, 게터/세터 정의 가능

🔗 캡슐화

var date: Date
    get() = Date(millis)
    set(value) {
        millis = value.time
    }

만약 Date를 활용한 객체가 더 이상 사용할 수 없는데 해당 프로퍼티를 많이 참조하고 있다면, millis라는 별도의 프로퍼티에 옮겨 date 프로퍼티에 데이터를 저장하지 않고 랩/언랩할 수 있다.

🔗 프로퍼티와 함수

프로퍼티는 get을 재정의해서 함수처럼 나타낼 수 있다.

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

위는 프로퍼티로 알고리즘을 나타낸 예시인데, 큰 컬렉션의 경우 많은 계산량이 필요할 수 있다. 하지만 관습적으로 이런 게터에 그러한 계산량이 필요하다고는 예상하지 않는다. 따라서 이런 처리는 함수로 구현해야 한다.

프로퍼티 대신 함수를 사용하는 경우

  • 연산 비용이 높거나, 복잡도가 O(1)보다 큰 경우
  • 비즈니스 로직을 포함하는 경우
    • 로깅, 리스너 통지, 바인드된 요소 변경과 같은 단순 동작 이상을 할것이라고 기대하지 않는다.
  • 결정적이지 않은 경우 (멱등x)
    • 같은 동작을 연속적으로 두 번 했는데 다른 값이 나올 수 있는 경우는 함수 사용
  • 변환의 경우
    • Int.ToDouble()과 같이 변환함수로 나타내는 것이 관습적이다.
  • 게터에서 상태 변경이 일어나는 경우
    • get하는데 왜 상태변경을 ?!?! -> 함수로 나타내자

프로퍼티로 나타내는 경우

  • 상태를 추출/설정
    • 특별한 이유가 없다면 함수를 사용하면 안된다.
//Bad
class UserIncorrect {
	private var name: String = ""
    
    fun getName() = name
    
    fun setName(name: String) {
    	this.name = name
    }
}

//Good
class UserCorrect {
	var name: String = ""
}
profile
💻 ☕️ 🏝 🍑 🍹 🏊‍♀️

0개의 댓글