가시성과 관련된 제한은 한번 정해지면 변경하기 어렵다.
클래스의 상태를 나타내는 프로퍼티를 외부에서 변경할 수 있다면 클래스는 자신의 상태를 보장할 수 없다.
class CounterSet<T>(
private val innerSet: MutableSEt<T> = setOf()
) : MutableSet<T> by innerSet {
var elementsAdded: Int = 0
private set
}
위처럼 세터만 private으로 만드는 코드를 많이 사용한다. 코틀린에서는 구체 접근자의 가시성을 제한해 모든 프로퍼티를 캡슐화하는것이 좋다.
가시성이 제한될수록 클래스의 변경을 쉽게 추적할 수 있으며, 프로퍼티의 상태를 더 쉽게 이해할 수 있다. 또한 상태 변경은 동시성을 처리할 때 중요하며 이는 병렬 프로그래밍에서 문제가 된다.
가시성 한정자 사용하기
클래스 멤버의 경우 아래 4가지 가시성 한정자(visibility modifier)를 사용할 수 있다.
- public(default) 어디에서나 볼 수 있다.
- private 클래스 내부에서만 볼 수 있다.
- protected 클래스와 서브클래스 내부에서만 볼 수 있다.
- internal 모듈 내부에서만 볼 수 있다.
톱레벨 요소에는 아래 세가지 가시성 한정자를 사용할 수 있다.
- public(default) 어디에서나 볼 수 있다.
- private 같은 파일 내부에서만 볼 수 있다.
- internal 모듈 내부에서만 볼 수 있다.
위에서 모듈은 함께 컴파일되는 코틀린 소스를 의미한다.
API를 상속할 때 오버라이드해서 가시성을 제한할 수는 없다. 이는 서브클래스가 슈퍼클래스로도 사용될 수 있기 때문이며 이것이 상속보다 컴포지션을 선호하는 대표적인 이유 중 하나이다.
정리
아래 이유로 요소의 가시성은 최대한 제한적인 것이 좋다.
- 인터페이스가 작을수록 이를 공부하고 유지하는 것이 쉽다.
- 최대한 제한이 되어 있어야 변경하기 쉽다.
- 클래스의 상태를 나타내는 프로퍼티가 노출되어 있다면, 클래스가 자신의 상태를 책임질 수 없다.
- 가시성이 제한되면 API의 변경을 쉽게 추적할 수 있다.
Reference
- 이펙티브 코틀린 - 프로그래밍 인사이트, 마르친 모스칼라 지음, 윤인성 옮김
개인적인 기록을 위해 작성된 글이라 잘못된 내용이 있을 수 있습니다.
오류가 있다면 댓글을 남겨주세요.