fun Context.showMessage(
message: String,
duration: MessageLength = MessageLength.LONG
) {
val toastDuration = when(duration) {
SHORT -> Length.LENGTH_SHORT
LONG -> Length.LENGTH_LONG
}
Toast.makeText(this, message, toastDuration).show()
}
enum class MessageLength { SHORT, LONG }
위 showMessage 함수는 다른 타입으로도 메시지를 출력할 수 있게 하고자 붙인 이름이지만 개발자는 당연히 토스트를 출력할거라고 생각할 수 있다.
따라서 이 함수가 무엇을 하는지 명확하게 설명하고 싶다면 아래처럼 KDoc으로 주석을 붙여 주는 것이 좋다.
/**
* Universal way for the project to display a short
* message to a user.
* @param message 설명
* @param duration 설명
*/
fun Context.showMessage(
// ...
)
규약
규약이 적절하게 정의되어 있다면 클래스를 만든 사람은 클래스가 어떻게 사용될 지 걱정하지 않아도 된다.
서로가 규약을 존중하면 독립적으로 작업해도 모든것이 정상적으로 기능할 것이다.
규악 정의하기
규약 정의를 위한 대표적인 몇가지 방법
- 이름
- 주석과 문서
- 타입
주석을 써야 할까?
대부분의 기능은 이름으로 무엇을 하는지 확실하게 알 수 있으므로 주석을 활용한 추가적인 설명이 필요가 없다.
fun List<Int>.product() = fold(1) { acc, i -> acc * i }
여기에 주석을 다는 것은 코드를 산만하게 만드는 노이즈이다.
KDoc 형식
주석으로 함수를 문서화할 때 사용하는 공식적인 형식을 KDoc이라고 부른다.
KDoc은 /**
로 시작해 */
로 끝나며 아래와 같은 구조를 가지고 있다.
- 첫번째 부분은 요소에 대한 요약 설명이다.
- 두번째 부분은 상세 설명이다.
- 이어지는 줄은 모두 태그로 시작하며, 이러한 태그는 추가적인 설명을 위해 사용된다.
사용될 수 있는 태그는 아래와 같다.
@param
함수 파라미터 또는 클래스, 프로퍼티, 함수 타입 파라미터@return
함수의 리턴 값을 문서화@constructor
클래스의 기본 생성자를 문서화@receiver
확장 함수의 리시버를 문서화@property <name>
명확한 이름을 가진 클래스의 프로퍼티를 문서화, 기본 생성자에 정의된 프로퍼티에 사용한다.@throws <class>, @exception <class>
메소드 내부에서 발생할 수 있는 예외를 문서화@sample <identifier>
정규화된 형식 이름을 사용해 함수의 사용 예를 문서화한다.@see <identifier>
특정한 클래스 또는 메소드에 대한 링크 추가@author
요소의 작성자 지정@since
요소에 대한 버전 지정@supress
이를 지정하면 만들어지는 문서에서 해당 요소가 제외된다. 외부에서는 사용할 수 있지만, 공식 API에 포함할 필요가 없는 요소에 지정
타입 시스템과 예측
클래스가 어떤 동작을 할 것이라 예측되면, 서브클래스도 이를 보장해야 하며 이를 리스코프 치환 원칙(Liskov substitution principle)이라고 부른다.
표준 라이브러리나 인기있는 라이브러리의 대부분 클래스는 서브클래스에 대한 자세한 설명과 규약을 갖고 있다.
interface Car {
/**
* 자동차의 방향을 변경합니다.
* @param angle 바퀴 축의 각도를 지정합니다.
* 라디안 단위로 지정하며, 0은 직진을 의미합니다.
*/
fun setWheelPosition(angle: Float)
/**
* 자동차의 속도가 0이 될때까지 감속합니다.
* @param pressure 브레이크 페달을 사용하는 비율을 지정합니다.
* 0 - 1 사이의 숫자를 지정합니다.
*/
fun setBreakPedal(pressure: Double)
}
이러한 설명과 규약은 인터페이스를 유용하게 만든다.
조금씩 달라지는 세부 사항
프로그래밍 언어에서도 구현의 세부 사항은 조금씩 달라질 수 있지만, 최대한 많이 보호하는 것이 좋다.
캡슐화로 최대한 허용되는 범위를 지정해주면 사용자가 구현에 신경을 많이 쓸 필요가 없어지므로 더 많은 자유를 갖게 된다.
정리
특히 외부 API를 구현할 때는 규약을 잘 정의해야 한다.
이러한 규약은 이름, 문서, 주석, 타입을 통해 구현할 수 있다.
Reference
- 이펙티브 코틀린 - 프로그래밍 인사이트, 마르친 모스칼라 지음, 윤인성 옮김
개인적인 기록을 위해 작성된 글이라 잘못된 내용이 있을 수 있습니다.
오류가 있다면 댓글을 남겨주세요.