API를 설계할 때 가능한 간결한 API를 선호하는데 여러 가지 이유가 있습니다.
- 작은 인터페이스는 배우기 쉽고 유지하기 쉽습니다.
- 변경을 가할 때는 기존의 것을 숨기는 것보다 새로운 것을 노출하는 것이 쉽습니다.
- 클래스의 상태를 나타내는 프로퍼티를 외부에서 변경할 수 있다면, 클래스는 자신의 상태를 보장할 수 없습니다.
class CounterSet<T>(
private val innnerSet: MutableSet<T> = setOf()
) : MutableSet<T> by innerSet {
var elementsAdd: Int = 0
private set
override fun add(element: T): Boolean {
elementsAdded++
return innerSet.add(element)
}
override fun addAll(elements: Collection<T>): Boolean {
elementsAdded += elements.size
return innerSet.addAll(elements)
}
}
일반적으로 Kotlin에서는 위 처럼 구체 접근자의 가시성을 제한해서 모든 프로퍼티를 캡슐화하는 것이 좋습니다.
가시성이 제한될수록 클래스의 변경을 쉽게 추적할 수 있으며, 프로퍼티의 상태를 더 쉽게 이해할 수 있습니다. 이는 동시성을 처리할 때 중요합니다.
가시성 한정자 사용하기
내부적인 변경 없이 작은 인터페이스를 유지하고 싶다면, 가시성을 제한하면 됩니다. 기본적으로 클래스와 요소를 외부에 노출할 필요가 없다면, 가시성을 제한해서 외부에서 접근할 수 없게 만드는 것이 좋습니다. 가시성 제한은 가시성 한정자(visibility modifier)를 활용해서 구현합니다.
클래스 멤버의 경우 아래와 같은 4개의 가시성 한정자를 사용할 수 있습니다.
- public(defualt): 어디에서나 볼 수 있습니다.
- private: 클래스 내부에서만 볼 수 있습니다.
- protected: 클래스와 서브클래스 내부에서만 볼 수 있습니다.
- internal: 모듈 내부에서만 볼 수 있습니다.
톱레벨 요소에서는 세 가지 가시성 한정자를 사용할 수 있습니다.
- public: 어디에서나 볼 수 있습니다.
- private: 같은 파일 내부에서만 볼 수 있습니다.
- internal: 모듈 내부에서만 볼 수 있습니다.
참고로 Kotlin에서 모듈이란 함께 컴파일되는 코틀린 소스를 의미합니다. 따라서 아래의 항목들을 의미합니다.
- Gradle 소스 세트
- Maven 프로젝트
- IntelliJ IDEA 모듈
- Ant 태스크 한 번으로 컴파일 되는 파일 세트
만약 모듈이 다른 모듈에 의해서 사용될 가능성이 있다면, internal을 사용해서 공개하고 싶지 않은 요소를 숨깁니다.
요소가 상속을 위해 설계되어 있고, 클래스와 서브 클래스에서만 사용되게 만들고 싶다면, protected를 사용합니다.
동일한 파일 또는 클래스에서만 요소를 사용하게 만들고 싶다면 private을 사용합니다.
정리
필자는 경험적으로 요소의 가시성은 최대한 제한하는 것이 좋다고 이야기 하고 있습니다. 그리고 보이는 요소들은 모두 public API로서 사용되면 아래와 같은 이유들로 최대한 단순하게 하는 것이 좋습니다.
- 인터페이스가 작을 수록 이를 공부하고 유지하는 것이 쉽습니다.
- 최대한 제한이 되어 있어야 변경하기 쉽습니다.
- 클래스의 상태를 나타내는 프로퍼티가 노출되어 있다면, 클래스가 자신의 상태를 책임질 수 없습니다.
- 가시성이 제한되면 API의 변경을 쉽게 추적할 수 있습니다.
'Kotlin' 카테고리의 다른 글
[Effective Kotlin] 32 - 추상화 규칙을 지켜라 (0) | 2023.09.02 |
---|---|
[Effective Kotlin] 31 - 문서로 규약을 정의하라 (0) | 2023.08.26 |
[Effective Kotlin] 29 - 외부 API를 Wrap해서 사용하라 (0) | 2023.08.13 |
[Effective Kotlin] 28 - API 안정성을 확인하라 (0) | 2023.08.05 |
[Effective Kotlin] 27 - 변화로부터 코드를 보호하려면 추상화를 사용하라 (0) | 2023.07.30 |