Kotlin Clean Code

0
post-thumbnail


출처 : 코틀린으로 클린코드

안드로이드 위클리를 읽어보다가, 코드를 깔끔하게 짜야한다고 생각해서 번역을 해보았다.
이정도만 지켜도 어느회사에서 사랑받는 개발자가 아닐까 싶다
(물론 주인장의 코드는 제리 삼지창이지만..)

🧶 1. 코딩은 단거리 경주가 아니라 마라톤이다.

Kotlin과 함께 자바와는 다른 간결한 코드를 짤수있다.
?를 통한 Null check , 엘비스 표현식, 변수의 간편화 무수히 많다.
우리는 코드를 어떻게 짜는가에 대한 모범사례를 읽어보면서, 하나씩 정리할 생각이다.
지금 못한다고 좌절에 빠지지 말자. 코드는 장거리 경주이기 때문에 서서히 변해가면 된다 ^^

클린 코드는 읽을수있는것이다. 그것은 스토리를 말해준다. - Clean code BOB


클린 코드는 독자들에게 의도를 명확하게 표현하는 것이다 - Venkat Subramaniam

🎆 2. 의미 있는 이름

코드를 작성할때 패키지, 클래스, 함수, 변수를 만든다.
그리고 이름을 선택할때, 변수나 클래스라 할지라도 구성요소에 대한 의도가 들어가있어야 한다.
그 의도에 대해서 세가지 질문에 답해야 한다.

    1. 왜 필요해?
    1. 그게 뭔데?
    1. 어떻게 쓰는데?

한번 예제를 들고와서 비교를 해보자.

Sample 1


data class PathParts(val directory: String, val fileName: String)

fun splitPath(path: String) =
  PathParts(
      path.substringBeforeLast('/', ""),
      path.substringAfterLast('/'))

data class GetFile(val d: String, val n: String)

val pattern = Regex("(.+)/([^/]*)")

fun files(ph: String): PathParts {
val match = pattern.matchEntire(ph)
      ?: return PathParts("", ph)

return PathParts(match.groupValues[1],
    match.groupValues[2])

위와 아래의 코드를 보자.

아래의 코드는 변수명을 개떡같이 써놓았다. 심지어 Return값은 무엇을 리턴하는지 알아보기도 힘들다.
위의 코드는 변수명으로 이해할수있다.

아.. 첫번째 변수는 폴더 디렉토리고, 두번째는 파일명이구나

이처럼 변수를 명확하게 표현하는것은 중요하다.

Sample 2


class Book(val title: String?, val publishYear: Int?)

fun displayBookDetails(book: Book) {
  val title = book.title
  if (title == null)
      throw IllegalArgumentException("Title required")
  val publishYear = book.publishYear
  if (publishYear == null) return

  println("$title: $publishYear")
}


class Book(val title: String?, val publishYear: Int?)

fun displayBookDetails(book: Book) {
  val title = book.title ?: 
throw IllegalArgumentException("Title required")
  val publishYear = book.publishYear ?: return

  println("$title: $publishYear")
}

두번째 샘플은 확연하게 보일것이다.
Kotlin의 가장 큰장점 NullCheck를 활용하지 않았다.
물론 읽기에는 서로 둘다 나쁘지 않다.
하지만 자바식 코틀린은 경계할 필요가 있다.

자바식 코틀린은 경계하자

Sample 3

users.filter{ it.job == Job.Developer }
  .map{ it.birthDate.dayOfMonth }
  .filter{ it <= 10 }
  .min()


users.filter{ user -> user.job == Job.Developer }
  .map{ developer -> developer.birthDate.dayOfMonth }
  .filter { birthDay -> birthDay <= 10 }
  .min()

내가 가장많이 하는 실수이다.
위와 아래의 코드는 같지만, 수신 객체의 명을 정확하게 표현했냐 안했냐의 차이다.
그 하나의 차이만으로 코드가 읽기 쉬워진다.

불변성

코틀린을 사용하면서, 우리는 불변성 함수를 더 편하게 만들수있다.

  • var보단 val을 선호하라
  • mutable보단 read-only를 선호하라
  • copy()가 사용되는 data class를 선호하라

🧨 3. 함수

함수는 최대한 잘게 쪼개야 한다.

함수가 길어지면

  • 테스트하기 어렵다.
  • 읽기가 어렵다.
  • 재사용이 어렵다.
  • 중복으로 이어진다.
  • 유지보수에 불리하다.
  • 디버깅 하기 어렵다.

그리고 적용해야할 규칙이 있다.

  • 함수의 들여쓰기 수준(깊이)는 최대 2레벨까지 줄인다.
  • 함수는 부작용이 일어나지 말아야한다.
  • 함수의 구체적인 설명이 이루어진 함수명이 수수께끼같은 짧은 함수명보다 좋다.
  • 코드를 쉽게 읽을 수 있을때까지 코드를 변경하고 재구성한다.
  • CQS 법칙을 적용한다.
  • if, else while은 한줄의 코드블럭으로 줄인다.
profile
쉽게 가르칠수 있도록 노력하자

0개의 댓글