Hanbit the Developer

Effective Kotlin | 2μž₯. 가독성 λ³Έλ¬Έ

Mobile/Kotlin

Effective Kotlin | 2μž₯. 가독성

hanbikan 2023. 6. 13. 18:51
πŸ’‘ 컴퓨터가 인식할 수 μžˆλŠ” μ½”λ“œλŠ” 바보라도 μž‘μ„±ν•  수 μžˆμ§€λ§Œ, 인간이 이해할 수 μžˆλŠ” μ½”λ“œλŠ” μ‹€λ ₯ μžˆλŠ” ν”„λ‘œκ·Έλž˜λ¨Έλ§Œ μž‘μ„±ν•  수 μžˆλ‹€. - Martin Flowler, <Refactoring>

μ•„μ΄ν…œ 11: 가독성을 λͺ©ν‘œλ‘œ μ„€κ³„ν•˜λΌ

인식 λΆ€ν•˜ κ°μ†Œ

일반적으둜 자주 μ‚¬μš©ν•˜λŠ” νŒ¨ν„΄μ„ ν™œμš©ν•  것

κ·Ήλ‹¨μ μ΄κ²Œ λ˜μ§€ μ•ŠκΈ°

κ²½ν—˜μ΄ λ§Žμ€ μ½”ν‹€λ¦° 개발자만 μ‰½κ²Œ 이해할 수 μžˆλŠ” μ½”λ“œκ°€ 있으면, μ œλ„ˆλŸ΄ν•˜κ²ŒλŠ” μ΄ν•΄ν•˜κΈ° μ–΄λ €μš΄ μ½”λ“œκ°€ λœλ‹€. κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  μ΄λŸ¬ν•œ ‘λΉ„μš©’을 μ§€λΆˆν•  λ§Œν•œ μ΄μœ κ°€ μžˆλ‹€λ©΄ νŠΈλ ˆμ΄λ“œ μ˜€ν”„λ₯Ό μ§„ν–‰ν•˜λŠ” μ˜΅μ…˜μ„ κ³ λ €ν•  수 μžˆλ‹€.

μ»¨λ²€μ…˜

μ•„μ΄ν…œ 12: μ—°μ‚°μž μ˜€λ²„λ‘œλ“œλ₯Ό ν•  λ•ŒλŠ” μ˜λ―Έμ— 맞게 μ‚¬μš©ν•˜λΌ

factorial() ν•¨μˆ˜λ₯Ό μ‰½κ²Œ ν‘œν˜„ν•˜κΈ° μœ„ν•΄ operator fun Int.not() = factorial()을 μž‘μ„±ν•˜μ—¬ μ‚¬μš©ν•˜λ©΄ ν˜Όλž€μŠ€λŸ½κ³  μ˜€ν•΄μ˜ μ†Œμ§€κ°€ μžˆλ‹€.

λΆ„λͺ…ν•˜μ§€ μ•Šμ€ 경우

μ‚¬λžŒμ— 따라 해석이 갈릴 수 μžˆλŠ” κ²½μš°μ—λŠ” infix λ˜λŠ” ν†±λ ˆλ²¨ ν•¨μˆ˜λ₯Ό ν™œμš©ν•˜μ—¬ 의미λ₯Ό λͺ…ν™•ν•˜κ²Œ ν•  것

κ·œμΉ™μ„ λ¬΄μ‹œν•΄λ„ λ˜λŠ” 경우

HTML DSL λ“± DSL(Domain Specific Language)λ₯Ό μ„€κ³„ν•˜λŠ” κ²½μš°μ—λŠ” κ·œμΉ™μ„ λ¬΄μ‹œν•΄λ„ λœλ‹€.

μ•„μ΄ν…œ 13: Unit?을 λ¦¬ν„΄ν•˜μ§€ 말라

fun isCorrect(key: String): Unit? = // ...
isCorrect(key) ?: return

μœ„μ™€ 같은 μ‹μœΌλ‘œ μ½”λ“œλ₯Ό μ‚¬μš©ν•  수 μžˆμœΌλ‚˜ μ΄ν•΄ν•˜κΈ° μ–΄λ ΅κ³  μ˜€ν•΄μ˜ μ†Œμ§€κ°€ μžˆλ‹€. λŒ€μ‹  λ‹€μŒκ³Ό 같이 μ‚¬μš©ν•˜λΌ:

fun isCorrect(key: String): Boolean = // ...
isCorrect(key) ?: return

μ•„μ΄ν…œ 14: λ³€μˆ˜ νƒ€μž…μ΄ λͺ…ν™•ν•˜μ§€ μ•Šμ€ 경우 ν™•μ‹€ν•˜κ²Œ μ§€μ •ν•˜λΌ

type inference(e.g. val num = 10)λŠ” 개발 μ‹œκ°„μ„ 쀄여주고 가독성이 ν–₯μƒλœλ‹€λŠ” μž₯점을 κ°–κ³  μžˆλ‹€.

ν•˜μ§€λ§Œ μ½λŠ” μž…μž₯μ—μ„œ λͺ…ν™•ν•˜μ§€ μ•Šμ€ 경우 νƒ€μž…μ„ λͺ…μ‹œν•¨μœΌλ‘œμ¨ 가독성을 λ†’μ—¬, λ°˜ν™˜ νƒ€μž…μ„ μ•ŒκΈ° μœ„ν•΄ ν•΄λ‹Ή ν•¨μˆ˜ μ •μ˜ νŒŒμΌμ„ μ—¬λŠ” λ“±μ˜ μ‹œκ°„ λ‚­λΉ„λ₯Ό 쀄일 수 μžˆλ‹€. λ˜ν•œ μ•ˆμ „μ„±λ„ 높아진닀.

// val data = getSomeData()
val data: UserData = getSomeData()

μ•„μ΄ν…œ 15: λ¦¬μ‹œλ²„λ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ°Έμ‘°ν•˜λΌ

μ—¬λŸ¬ 개의 λ¦¬μ‹œλ²„

μŠ€μ½”ν”„ 내뢀에 λ‘˜ μ΄μƒμ˜ λ¦¬μ‹œλ²„κ°€ μžˆλŠ” 경우 λͺ…μ‹œν•˜λŠ” 것이 μ’‹λ‹€.

run λ‚΄λΆ€μ—μ„œ this ν‚€μ›Œλ“œκ°€ κ²ΉμΉœλ‹€λ©΄ alsoλ₯Ό μ‚¬μš©ν•˜κ±°λ‚˜ this@Node와 같이 λ ˆμ΄λΈ”μ„ μ§€μ •ν•œλ‹€.

*λ ˆμ΄λΈ” 없이 λ¦¬μ‹œλ²„λ₯Ό μ‚¬μš©ν•˜λ©΄ κ°€μž₯ κ°€κΉŒμš΄ λ¦¬μ‹œλ²„λ₯Ό μ˜λ―Έν•œλ‹€.

DSL 마컀

μ•„μ΄ν…œ 16: ν”„λ‘œνΌν‹°λŠ” λ™μž‘μ΄ μ•„λ‹ˆλΌ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄μ•Ό ν•œλ‹€

getter 등을 μ΄μš©ν•΄ ν•¨μˆ˜μ²˜λŸΌ μž‘λ™ν•˜λŠ” ν”„λ‘œνΌν‹°λ₯Ό λ§Œλ“€μ§€ 말 것

ν”„λ‘œνΌν‹° λŒ€μ‹  ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 쒋은 κ²½μš°λŠ” λ‹€μŒκ³Ό κ°™λ‹€:

  • μ—°μ‚° λΉ„μš©μ΄ 높은 경우
  • λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ ν¬ν•¨ν•˜λŠ” 경우
  • 결정적이지 μ•Šμ€ 경우: 같은 λ™μž‘μ„ μ—°μ†μœΌλ‘œ 두 번 ν–ˆλŠ”λ° λ‹€λ₯Έ 값이 λ‚˜μ˜€λŠ” 경우
  • λ³€ν™˜μ˜ 경우
  • getterμ—μ„œ ν”„λ‘œνΌν‹°μ˜ μƒνƒœ 변경이 μΌμ–΄λ‚˜μ•Ό ν•˜λŠ” 경우

μ•„μ΄ν…œ 17: 이름 μžˆλŠ” μ•„κ·œλ¨ΌνŠΈλ₯Ό μ‚¬μš©ν•˜λΌ

val text = (1..10).joinToString("|") // X
val text = (1..10).joinToString(separator = "|") // O
val separator = "|"
val text = (1..10).joinToString(separator) // O

이름 μžˆλŠ” μ•„κ·œλ¨ΌνŠΈλŠ” μ–Έμ œ μ‚¬μš©ν•΄μ•Ό ν• κΉŒ?

  • sleep(100) → sleep(tileMillis = 100): ms인지 s인지 λͺ…ν™•ν•˜μ§€ μ•Šμ•˜λŠ”λ° 이λ₯Ό κ°œμ„ 
  • default argumentλ₯Ό κ°€μ§ˆ 경우(default argument e.g. fun add(isStable: Boolean = true))
  • 같은 νƒ€μž…μ˜ νŒŒλΌλ―Έν„°κ°€ λ§Žμ€ 경우
  • ν•¨μˆ˜ νƒ€μž…μ˜ νŒŒλΌλ―Έν„°κ°€ μžˆλŠ” 경우(λ§ˆμ§€λ§‰ 경우 μ œμ™Έ)

μ•„μ΄ν…œ 18: μ½”λ”© μ»¨λ²€μ…˜μ„ μ§€μΌœλΌ

μž₯점은 λ‹€μŒκ³Ό κ°™λ‹€:

  • μ–΄λ–€ ν”„λ‘œμ νŠΈλ₯Ό 접해도 μ‰½κ²Œ 이해할 수 μžˆλ‹€.
  • μ™ΈλΆ€ κ°œλ°œμžλ„ μ‰½κ²Œ 이해할 수 μžˆλ‹€.
  • μ½”λ“œλ₯Ό λ³‘ν•©ν•˜κ±°λ‚˜ μ΄λ™ν•˜λŠ” 것이 쉽닀.

도움이 λ˜λŠ” 도ꡬ:

  • IntelliJ Formatter
  • ktlink