단순성(Simplicity)
단순성(Simplicity)
사용자가 이해해야 하는 개념이 적을수록, 그리고 그 개념이 더 명시적으로 전달될수록 사용자의 정신적 모델은 더 단순해질 가능성이 높아요. 이는 API에서 연산(operation)과 추상화의 수를 제한함으로써 달성할 수 있어요.
라이브러리에서 내부 구현 세부 사항이 공개 API에 노출되지 않도록, 선언의 가시성(visibility)을 적절히 설정해야 해요. 공개용으로 명시적으로 설계되고 문서화된 API만 사용자에게 접근 가능해야 해요.
이 가이드의 다음 부분에서는 단순성을 높이는 몇 가지 지침을 논의할 거예요.
명시적 API 모드 사용하기
Kotlin 컴파일러의 explicit API mode 기능을 사용할 것을 권장해요. 이 기능은 라이브러리의 API를 설계할 때 의도를 명시적으로 드러내도록 강제해 주거든요.
명시적 API 모드에서는 다음을 해야 해요:
- 기본 공개 가시성에 의존하는 대신, 선언을 public으로 만들도록 가시성 수정자를 추가해야 해요. 이를 통해 무엇을 공개 API의 일부로 노출하는지 고려하게 돼요.
- 모든 공개 함수와 프로퍼티의 타입을 정의해서, 추론된 타입으로 인해 API가 의도치 않게 변경되는 것을 방지해야 해요.
기존 개념 재사용하기
API의 크기를 제한하는 한 가지 방법은 기존 타입을 재사용하는 거예요. 예를 들어 지속 시간(duration)용 새 타입을 만드는 대신 kotlin.time.Duration을 사용할 수 있어요. 이 방식은 개발을 간소화할 뿐만 아니라 다른 라이브러리와의 상호 운용성도 향상시켜요.
다만 서드파티 라이브러리의 타입이나 플랫폼별 타입에 의존할 때는 주의해야 해요. 이런 타입들이 라이브러리를 그 요소들에 묶어버릴 수 있거든요. 그런 경우 비용이 이점보다 클 수도 있어요.
String, Long, Pair, Triple 같은 공통 타입을 재사용하는 것은 효과적일 수 있어요. 하지만 도메인별 로직을 더 잘 캡슐화한다면 추상 데이터 타입을 개발하는 것을 막지는 마세요.
핵심 API를 정의하고 그 위에 구축하기
단순함으로 가는 또 다른 길은 제한된 핵심 연산 집합을 중심으로 작은 개념적 모델을 정의하는 거예요. 이 연산들의 동작이 명확히 문서화되면, 핵심 함수를 직접 기반으로 하거나 조합하는 새 연산을 개발해 API를 확장할 수 있어요.
예를 들어:
- Kotlin Flows API에서
filter와map같은 일반 연산은transform연산 위에 구축돼 있어요. - Kotlin Time API에서
measureTime함수는TimeSource.Monotonic을 사용해요.
핵심 구성 요소를 기반으로 추가 연산을 만드는 것이 종종 유익하지만, 항상 필요한 것은 아니에요. 기능을 확장하거나 다양한 입력에 더 폭넓게 적응하는 최적화되거나 플랫폼별인 변형을 도입할 기회를 찾을 수도 있어요.
사용자가 핵심 연산으로 사소하지 않은 문제를 해결할 수 있고, 동작을 변경하지 않고 추가 연산으로 해결책을 리팩터링할 수 있는 한, 개념적 모델의 단순성은 유지돼요.
더 알아보기
이 가이드의 다음 부분에서는 가독성(Readability)에 대해 배워요.