코틀린은 간결함 보다는 가독성을 좋게하는 데 목표를 두고 설계된 프로그래밍 언어다. 코틀린을 사용하면 깨끗하고 의미 있는 코드와 API를 쉽게 작성할 수 있다.
다음의 항목들을 참조하여 가독성 좋은 코드를 작성해보자.
1. 가독성을 목표로 설계하기
개발자는 코드를 작성하는 시간보다 읽는데 많은 시간을 소모한다. 따라서 항상 가독성을 생각하면서 코드를 작성해야 한다. 가독성이란 코드를 읽고 얼마나 빨게 이해할 수 있는지를 의미한다. 즉 코드 라인수를 무조건 짧게 작성하는게 능사가 아니므로 라인수가 길어지더라도 읽기 좋은 코드를 작성해야한다.
2. 의미에 맞게 연산자 오버로딩하기
코틀린의 모든 연산자는 연산자 대신 함수로도 호출 할 수 있다.
예) +a -> a.unaryPlus(), !a -> a.not()
코틀린에서 연산자 오버로딩을 지원하는데, 만약 관례에 어긋나는 의미를 이해하기 어려운 오버로딩 시 문제가 될 수 있다. 그렇기 때문에 의미가 명확하지 않다면, infix를 활용한 확장 함수를 사용하는 것이 좋다.
infix fun Int.timesRepeated(operation: ()->Unit) = {
repeat(this){ operation() }
}
val tripledHello = 3 timesRepeated { print("Hello") }. // HelloHelloHello 출력
예외적으로 DSL을 설계할 때는 연산자 오버로딩 규칙을 무시할 수 있다. 이 외에는 의미에 맞게 연산자 오버로딩을 사용해야하며, 꼭 연산자 같은 형태로 사용하고 싶다면 infix확장 함수 또는 탑-레벨 함수(top-level function)를 활용하자.
3. Unit?을 리턴하지 않기
코틀린에서 Unit은 자바의 Void와 비슷하며, 아래의 두 함수는 기본적으로 같다.
fun foo(){} fun foo():Unit{}
반환 타입이 Unit?인 경우 null을 반환할 수 있는데, 어떠한 함수가 의미있는 null을 반환한다는 것인지 반환할 것이 없다는 것인지 애매모호해진다. 코드에 대한 오해를 불러일으키기 쉬우므로 기본적으로 Unit?을 반환하거나 이를 기반으로 연산하지 않는 것이 좋다.
4. 변수 타입을 확실하게 지정하기
코틀린은 강력한 타입 추론 시스템을 갖추고 있다. 이는 개발 시간을 줄여주지만, 상황에 따라 가독성을 떨어뜨릴 수 있으므로 필요할 때는 명시적으로 타입을 지정하는 것이 좋다.
5. 리시버를 명시적으로 참조하기
여러개의 리시버가 존재하는 경우
다중 리시버
중첩된 스코프 내에 여러개의 리시버가 있는 경우 리시버를 명시적으로 사용하면 의미가 명확해지고, 코드를 안전하게 사용할 수 있을 뿐만아니라 가독성도 향상된다.
DSL 마커
코틀린 DSL을 사용할 때 중첩된 리시버에서 외부 리시버를 사용하는 것을 막는 DslMarker를 사용하거나 명시적인 리시버 참조를 통해 어떤 리시버의 함수인지는 명확하게 하면 가독성이 향상된다.
6. 프로퍼티는 동작이 아니라 상태를 나타내야한다
원칙적으로 프로퍼티는 상태를 나타내거나 설정하기 위한 목적으로만 사용하는 것이 좋으며, 다른 로직 등을 포함하지 않아야 한다.
프로퍼티 대신 함수를 사용하는 것이 좋은 경우
- 연산비용 또는 시간복잡도가 큰 경우
- 비즈니스 로직을 포함하는 경우
- 같은 동작을 두 번 연속적으로 했는데 다른 값이 나올 수 있는 경우
- 프로퍼티 게터에서 상태 변환가 발생하는 경우
7. 이름 있는 인자를 사용하자
함수에서 파라미터 이름을 사용하면 코드는 길어지지만, 명확해지고 파마미터 입력 순서와 상관 없으므로 안전해진다.
8. 코딩 컨벤션 지키기
코딩 컨벤션을 지키면 마치 한사람이 작성한 것 처럼 코드를 일관되게 유지하고, 가독성을 지킬 수 있다. IDE 기능 또는 ktlint와 같은 코드 정적 검사 도구를 사용하면 컨벤션을 지키는데 도움이 된다.
0개의 댓글