[Scala] deprecated annotation - 호환성을 보장하며 API 수정하기

크게는 구조의 변경을 위해서부터, 작게는 오타 수정까지 API를 수정할 일은 많이 있다. 하지만 API를 변경하는 것은 복잡하고, 오래 걸리고, 어려운 일이다.

deprecated

API를 변경한다고 해서, 전에 사용하던 API를 바로 지우면, 그전 API를 사용하는 사람들이 급격하게 코드를 바꿔야 한다. 반대로 지우지 않고 2개의 API를 둔다 면, 전 API를 사용하던 사람이 코드를 고치지 않을 뿐 아니라, 새로 코드를 작성하는 코드에도 사용하지 않아야 하는 API를 사용하게 돼서 결국 2벌의 코드를 유지 보수해야 한다. 이런 상황에서 사용하는 것이 deprecated annotation이다.

위의 예제와 같이 deprecated annotation을 붙이면 해당하는 함수를 호출하는 코드를 컴파일할 때, 컴파일은 되지만 경고 메시지를 출력해준다. 게다가 내부적으로 Java의 Deprecated annotation을 더해주기 때문에, 자바 코드에서 호출해도 경고 메시지가 출력된다.

사실 Scala의 deprecated annotation은 Java의 Deprecated annotation과 에러 메시지와 version을 정해줄 수 있다는 것 외에는 큰 차이가 없다. 그렇기에 Scala는 다른 annotation을 더 지원한다.

deprecatedName

함수의 type signature를 바꾸는 일만큼, 함수의 type signature는 그대로 두고, 함수 인자의 이름만 바꿔야 하는 일도 많이 생긴다. 그 이유는 다양한데 기존에 사용했던 이름이 부적절했기 때문일 수도 있고, 함수의 동작이 바뀌면서 넘겨야 하는 인자가 변했지만, 우연히 타입은 같은 경우였을 수도 있다.

Java는 named parameter를 지원하지 않기 때문에 인자의 이름만 변경하는 경우가 문제 되지 않는다. 하지만 Scala처럼 named parameter를 지원하는 언어에서는 함수의 이름을 바꾸는 것도 문제가 될 수 있다. 이럴 때 사용하기 위한 것이 deprecatedName이라는 annotation이다. deprecatedName을 이용하면 아래와 같이 새 이름과 deprecated 된 이름 모두 쓸 수 있다. deprecated 된 이름을 쓰면 컴파일 시 경고 메시지를 출력하지만, 성공적으로 컴파일 된다.

처음 코드를 작성할 때 수정할 일이 없도록 코드를 작성하는 것이 가장 좋겠지만, 현실적으로 그런 것은 불가능하다. 그래서 Scala를 이용해 라이브러리를 작성할 때는 deprecated annotation을 이용해서 하위 호환성을 보장하며 코드를 수정하고 적당한 시기에 deprecated 된 코드를 지운다.

deprecated 된 코드를 오래 들고 있을수록 라이브러리를 사용하는 사람에게는 변화를 반영할 여유를 주게 되지만, 라이브러리를 작성하는 입장에서는 쓸데없는 짐을 지고 가는 것이기도 하다. 그래서 일반적인 라이브러리 개발의 경우 major version up 혹은 minor version up에서 deprecated 된 부분을 지우는 것이 일반적이지만, in-house 개발일 경우 deprecated annotation을 사용하지 않고 바로 코드를 지우기도 한다. deprecated 된 코드를 언제 지우는가는 전적으로 개발자가 프로젝트의 성격을 보고, 라이브러리를 사용하는 목적을 보고 적절히 선택해야 한다.


댓글

이 블로그의 인기 게시물

[C++] enum class - 안전하고 쓰기 쉬운 enum

RAII는 무엇인가

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

[Python] cache 데코레이터로 최적화하기

[Web] SpeechSynthesis - TTS API