Study/이펙티브코틀린
Item 16. 프로퍼티는 동작이 아니라 상태를 나타내야한다
주지민
2022. 3. 22. 02:07
반응형
본 포스트는 사내 스터디를 진행하며 정리한 포스트입니다
1. 코틀린의 프로퍼티
- 코틀린의 프로퍼티와 자바의 필드는 비슷해보이지만 완전히 다른 개념이다
- var로 정의되는 프로퍼티
- 기본적으로 사용자 정의 Setter와 Getter를 가질 수 있다
- field: 프로퍼티의 데이터를 저장해두는 백킹 필드 ( 따로 만들지 않아도 디폴트로 생성됨 )
- 파생 프로퍼티라고 불린다
var name: String? = null
get() = field?.toUpperCase()
set(value) {
if (!value.isNullOrBlank()) {
field = value
}
}
- val로 정의되는 프로퍼티
- 읽기전용이기 때문에 field가 생성되지 않는다
- 이처럼 코틀린의 모든 프로퍼티는 디폴트로 캡슐화되어있다
- 프로퍼티는 필드가 필요없고 개념적으로는 접근자(val는 getter, var는 setter, getter)를 나타낸다
- 따라서 인터페이스에도 정의가능 ( val로 정의하여 getter를 구현해야함 )
interface Person {
val name: String
}
class A : Person {
override val name: String
get() = TODO("Not yet implemented")
}
2. 유의사항
- 앞서 말씀드린 내용처럼 프로퍼티를 함수 대신하여 사용할 수도 있지만, 그렇다고 완전히 대체해서 사용하는 것은 좋지 않다
- 안좋은 예
val Tree<Int>.sum: Int {
get() = when(this) {
is Leaf -> value
is Node -> left.sum + right.sum
}
}
- Tree.sum의 getter로 모든 요소를 돌며 합을 구하는 알고리즘을 정의
- 일단 관습적으로 getter에 어떠한 알고리즘이 있을 것이라고 예상하지 않는다
- 따라서 이러한 처리는 프로퍼티가 아닌 함수로 처리해야한다
- 원칙적으로 프로퍼티는 상태를 나타내거나 설정하기 위한 목적으로만 사용하는 것이 좋고, 다른 로직 등을 포함하지 않아야 한다
- 프로퍼티(상태 집합)로 사용하기 좋은 예
- 해당 프로퍼티를 함수로 정의할 경우 접두사로 get 혹은 set이 들어가기 적절한 경우
- 상태를 추출/설정할 때 ( 특별한 이유가 없다면 )
- 함수(행동)를 사용해야하는 예
- 연산비용이 높거나 복잡도가 O(1)보다 큰 경우
- 비즈니스 로직을 포함하는 경우 ( 프로퍼티는 단순한 동작 이상을 할 것이라고 예상되지 않는다 )
- 같은 동작을 연속적으로 두번 했는데 다른 결과값이 나올 경우
- 변환, 컨버터
- 게터에서 프로퍼티의 상태변화가 일어나는 경우
728x90
반응형