아이템 29 - 외부 API를 랩(wrap)해서 사용하라
외부 API를 직접 사용하는 대신 랩(wrapper)을 사용하면 코드의 유지 보수성과 유연성을 크게 향상시킬 수 있다. 이 글에서는 랩의 정의와 사용법에 대해 알아본다.
랩은 기존의 기능을 감싸는 코드로, 외부 API와 애플리케이션 코드 사이의 인터페이스 역할을 한다. 이를 통해 외부 API의 변경 사항이 애플리케이션 코드에 직접적인 영향을 미치지 않도록 하며, 코드의 가독성과 테스트 가능성을 높일 수 있다.
유지 보수성 향상
유연성 증가
가독성 향상
테스트 용이성
안전성 강화
먼저, 외부 API의 기능을 추상화한 인터페이스를 정의한다. 이 인터페이스는 애플리케이션 코드가 외부 API를 호출하는 방법을 명세한다.
interface ExternalApi {
fun fetchData(id: String): ApiResponse
}
이제, 외부 API를 실제로 호출하는 구현 클래스를 작성한다. 이 클래스는 외부 API의 모든 세부 사항을 처리한다.
class ExternalApiImpl : ExternalApi {
override fun fetchData(id: String): ApiResponse {
// 실제 외부 API 호출 로직
val response = // ...
return ApiResponse(response)
}
}
랩 클래스를 만들어 외부 API 호출을 감싼다. 이 클래스는 외부 API 인터페이스를 구현하고, 필요에 따라 추가적인 로직을 포함할 수 있다
class ExternalApiWrapper(private val externalApi: ExternalApi) : ExternalApi {
override fun fetchData(id: String): ApiResponse {
// 필요한 추가 로직
return externalApi.fetchData(id)
}
}
애플리케이션 코드에서는 외부 API 구현 대신 랩 클래스를 사용한다. 이를 통해 외부 API 변경 시 애플리케이션 코드에 미치는 영향을 최소화할 수 있다.
class SomeService(private val externalApi: ExternalApi) {
fun process(id: String): ProcessedData {
val data = externalApi.fetchData(id)
// 추가적인 비즈니스 로직
return ProcessedData(data)
}
}
fun main() {
val externalApi = ExternalApiImpl()
val apiWrapper = ExternalApiWrapper(externalApi)
val service = SomeService(apiWrapper)
val result = service.process("someId")
println(result)
}
장점도 있지만 랩을 사용하면서 단점도 존재한다.
추가 코드 작성
성능 오버헤드
추가적인 추상화
설계 및 유지 보수 비용 증가
잠재적 문제 은닉
외부 API를 랩핑하는 것은 많은 장점을 제공하지만, 단점도 고려하여 신중하게 사용해야 한다. 상황에 맞게 랩핑을 적용하여 코드의 품질을 향상시키는 것이 중요하다.