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으로 하면 나중에 좁히기가 매우 어렵다. 그래서 처음엔 좁게 시작하고 필요할 때 넓히는 것이 일반적이다.