Kotlin ‐ 가시성을 최소화하라[Effective Kotlin Item 29] - thought-corner/Backend-PlayGround GitHub Wiki
가시성을 최소화하라
- API를 설계할 때 간결한 API를 선호하는 데는 여러 가지 이유가 있다.
왜 가시성을 최소화해야 하는가?
- 외부에 노출하는 것이 적을수록, 변경할 자유가 커진다.
- 첫째, 상태를 나타내는 프로퍼티를 노출하면 클래스의 불변식을 보장하기 어렵다. 외부에서 마음대로 상태를 바꿀 수 있으면 객체가 항상 유효한 상태를 유지한다고 보장할 수 없다.
// ❌ Bad - 외부에서 elementsAdded를 직접 조작할 수 있다
class CounterSet<T>(
private val innerSet: MutableSet<T> = mutableSetOf()
) : MutableSet<T> by innerSet {
var elementsAdded: Int = 0 // ❌ 외부에서 set 가능 → 불변식 깨짐
private set // 이렇게 막아야 한다
}
- 둘째, 가시성이 작을수록 변경을 추적하기 쉽다.
- 셋째, 노출이 적으면 내부 구현을 자유롭게 바꿀 수 있다.
코틀린의 가시성 한정자
| 한정자 |
범위 |
public(기본) |
어디서나 |
private |
그 클래스 내부에서만 |
protected |
그 클래스 + 하위 클래스에서만 |
internal |
같은 모듈 안에서만 |
internal은 코틀린이 강조하는 한정자이다. 모듈 내부에서는 공유하되, 외부 모듈 등에서는 감추고 싶을 때 사용한다.
- 그러나 가시성 한정자는 상속을 통해 우회될 수 있고, 리플렉션으로도 뚫린다. 그래서 보안 경계가 아니라 의도를 드러내고 실수를 막는 장치로 이해해야 한다.
- 또한 API를 만들 때 한 번 public으로 하면 나중에 좁히기가 매우 어렵다. 그래서 처음엔 좁게 시작하고 필요할 때 넓히는 것이 일반적이다.