Chapter 2 가독성

λ§ˆν‹΄ 파울러(Martin Flowler), <λ¦¬νŽ™ν„°λ§>
컴퓨터가 인식할 수 μžˆλŠ” μ½”λ“œλŠ” 바보라도 μž‘μ„±ν•  수 μžˆμ§€λ§Œ,
인간이 이해할 수 μžˆλŠ” μ½”λ“œλŠ” μ‹€λ ₯ μžˆλŠ” ν”„λ‘œκ·Έλž˜λ¨Έλ§Œ μž‘μ„±ν•  수 μžˆλ‹€.

코틀린은 간결성을 λͺ©ν‘œλ‘œ μ„€κ³„λœ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄κ°€ μ•„λ‹ˆλΌ, 가독성(readability)을 μ’‹κ²Œ ν•˜λŠ” 데 λͺ©ν‘œλ₯Ό 두고 μ„€κ³„λœ ν”„λ‘œκ·Έλž˜λ° 언어이닀.

코틀린을 μ‚¬μš©ν•˜λ©΄ κΉ¨λ—ν•˜κ³  의미 μžˆλŠ” μ½”λ“œμ™€ APIλ₯Ό μ‰½κ²Œ μž‘μ„±ν•  수 μžˆλ‹€.

코틀린은 μš°λ¦¬κ°€ μ›ν•˜λŠ” 것을 μˆ¨κΈ°κ±°λ‚˜ κ°•μ‘°ν•  수 있게 ν•˜λŠ” κΈ°λŠ₯을 많이 μ œκ³΅ν•œλ‹€.

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

λ‘œλ²„νŠΈ C λ§ˆν‹΄(Robert C. Martin)
κ°œλ°œμžκ°€ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” λ°λŠ” 1λΆ„ κ±Έλ¦¬μ§€λ§Œ,
이λ₯Ό μ½λŠ”λ°λŠ” 10뢄이 κ±Έλ¦°λ‹€.

ν”„λ‘œκ·Έλž˜λ°μ€ 쓰기보닀 읽기가 더 μ€‘μš”ν•˜λ‹€.

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

가독성은 μ‚¬λžŒμ— 따라 λ‹€λ₯΄κ²Œ λŠλ‚„ 수 μžˆλ‹€.

μΈμ§€λΆ€ν•˜(cognitive load)

ν•™μŠ΅μ΄λ‚˜ 과제 ν•΄κ²° κ³Όμ •μ—μ„œ 인지적 μš”κ΅¬λŸ‰μ΄ μš”κ΅¬λœλ‹€.
μ–΄λ–€ 정보가 ν•™μŠ΅λ˜κΈ° μœ„ν•΄μ„œλŠ” λ™μž‘μƒμ˜ κΈ°μ–΅ μ•ˆμ—μ„œ 정보가 μ²˜λ¦¬λ˜μ–΄μ•Ό ν•˜λŠ”λ°
μ΄λŠ” λ™μž‘μƒ 기얡이 μ²˜λ¦¬ν•΄ λ‚Ό 수 μžˆλŠ” μ •λ³΄μ˜ 양보닀 μ²˜λ¦¬ν•΄μ•Ό ν•  정보가 많으면 λ¬Έμ œκ°€ 생기며,
이 λ•Œ μΈμ§€λΆ€ν•˜κ°€ λ°œμƒν•œλ‹€.

Code A

Β 





if (person != null && person.isAdult) {
  view.showPerson(person)
} else {
  view.showError()
}

Code B

person?.takeIf { it.isAdult }
  ?.let(view::showPerson)
  ?: view.showError()

Code A κ°€ Code B 보닀 읽기 μ‰¬μš΄ 이유

  • 일반적인 κ΄€μš©κ΅¬(if/else, &&, λ©”μ„œλ“œ 호좜)을 μ‚¬μš©ν•˜κ³  μžˆλ‹€.
  • μ½”ν‹€λ§μ—μ„œ μ‚¬μš©μ€‘μΈ κ΄€μš©κ΅¬(μ•ˆμ „ν˜ΈμΆœ ?., takeIf, let, Elvis μ—°μ‚°μž, ν•¨μˆ˜ 레퍼런슀) 등을 μ‚¬μš©ν•¨μœΌλ‘œμ¨ μ½”ν‹€λ¦° μˆ™λ ¨μžλ“€λ§Œμ„ μœ„ν•œ μ½”λ“œμ΄λ‹€.
  • Code A κ°€ κ΅¬ν˜„μ„ μ΄ν•΄ν•˜λŠ”κ²ƒμ΄ 쉽고, μˆ˜μ • 및 디버깅이 쉽닀.

μœ„ 두 μ½”λ“œλŠ” λ™μž‘μƒ μ‹€ν–‰ 결과도 λ‹€λ₯΄λ‹€.(Code B λŠ” showPerson μ—μ„œ null 을 λ°˜ν™˜ν•˜λ©΄ showError λ₯Ό ν˜ΈμΆœν•œλ‹€.)

μΈμ§€λΆ€ν•˜λ₯Ό μ€„μ΄λŠ” λ°©ν–₯으둜 μ½”λ“œλ₯Ό μž‘μ„±ν•˜λΌ.

극단적이 λ˜μ§€ μ•ŠκΈ°

κ°€λ³€ ν”„λ‘œνΌν‹°λŠ” μ“°λ ˆλ“œμ™€ κ΄€λ ¨λœ 문제λ₯Ό λ°œμƒμ‹œν‚¬ 수 μžˆμœΌλ―€λ‘œ, 슀마트 μΊμŠ€νŒ…μ΄ λΆˆκ°€λŠ₯ν•˜λ‹€.

이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ μ•ˆμ „ν˜ΈμΆœ(?.) let을 μ‚¬μš©ν•œλ‹€. 이 외에도 let을 μ‚¬μš©ν•˜λŠ” κ²½μš°λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

  • 연산을 μ•„κ·œλ¨ΌνŠΈλ‘œ 처리 ν›„λ‘œ 이동할 λ•Œ
print(students.filter{}.joinToString{})
students.filter{}.joinToString{}.let{::print}
  • λ°μ½”λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•΄μ„œ 객체λ₯Ό 랩(포μž₯)ν•  λ•Œ

μ»¨λ²€μ…˜

invoke ν•¨μˆ˜

이름 없이 κ°„νŽΈν•˜κ²Œ 호좜될 수 μžˆλŠ” ν•¨μˆ˜

class Test {
  operator fun invoke(str: String) {
    print(str)
  }
}

fun main() {
  val test = Test()
  test("wow")
}

μœ„μ™€ 같이 test.invoke(str) 둜 μ‚¬μš©ν•΄μ•Ό ν•  것 κ°™μ§€λ§Œ,
이λ₯Ό λ¬΄μ‹œν•˜κ³  test(str) 둜 μ‚¬μš© κ°€λŠ₯ν•˜λ“―μ΄ 이름을 μƒλž΅ν•  수 μžˆλ‹€.

  • μ—°μ‚°μžλŠ” μ˜λ―Έμ— 맞게 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.
  • λžŒλ‹€λ₯Ό λ§ˆμ§€λ§‰ μ•„κ·œλ¨ΌνŠΈλ‘œ μ‚¬μš©ν•œλ‹€.

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

μ½”ν‹€λ¦°μ—μ„œλŠ” λ‹€μŒκ³Ό 같이 λŒ€μ‘λ˜λŠ” μ—°μ‚°μžμ™€ μ˜€λ²„λ‘œλ”©μ„ μ§€μ›ν•œλ‹€.

μ—°μ‚°μž λŒ€μ‘λ˜λŠ” ν•¨μˆ˜
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
++a a.inc()
--a a.dec()
a+b a.plus(b)
a-b a.minus(b)
a*b a.times(b)
a/b a.div(b)
a..b a.rangeTo(b)
a in b b.contains(a)
a+=b a.plusAssign(b)
a-=b a.minusAssign(b)
a*=b a.timesAssign(b)
a/=b a.divAssign(b)
a==b a.equals(b)
a>b a.compareTo(b)>0
a<b a.compareTo(b)<0
a>=b a.compreTo(b)>=0
a<=b a.compareTo(b)<=0

νŒ©ν† λ¦¬μ–Όμ„ κ³„μ‚°ν•˜κΈ° μœ„ν•΄ ! μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜λ©΄ μ•ˆλœλ‹€. (관둀에 어긋남)

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

μ˜λ―Έκ°€ λͺ…ν™•ν•˜μ§€ μ•Šλ‹€λ©΄ infix λ₯Ό ν™œμš©ν•œ ν™•μž₯ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.

μ€‘μœ„(infix) ν•¨μˆ˜

λ‘κ°œμ˜ λ³€μˆ˜ κ°€μš΄λ° μ˜€λŠ” ν•¨μˆ˜

infix fun String.add(other:String): String {
  return this + other
}
val string = "Hello" add "World"
System.out.println(string)        // HelloWorld
operator fun Int.times(operation: () -> Unit): () -> Unit = {
  repeat(this) { operation() }
}

3 * { print("Hello") }              // HelloHelloHello

ν•¨μˆ˜κ°€ κ΄€λ‘€λ₯Ό μΆ©μ‘±ν•  지 μ•„λ‹Œμ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ„ λ•ŒλŠ” infix ν•¨μˆ˜λ‘œ μ‚¬μš©ν•˜λΌ

infix fun Int.timesRepeated(operation: () -> Unit) = {
  repeat(this) { operation() }
}

val tripledHello = 3 timesRepeated { print("Hello") }
tripledHello()                    // HelloHelloHello

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

도메인 νŠΉν™” μ–Έμ–΄(Domain Specific Language, DSL)λ₯Ό 섀계할 λ•ŒλŠ” μ‚¬μš©ν•΄λ„ λœλ‹€.

정리

μ—°μ‚°μž μ˜€λ²„λ‘œλ”©μ€ κ·Έ μ΄λ¦„μ˜ μ˜λ―Έμ— 맞게 μ‚¬μš©ν•˜λΌ. μ—°μ‚°μž μ˜λ―Έκ°€ λͺ…ν™•ν•˜μ§€ μ•Šλ‹€λ©΄, μ—°μ‚°μž μ˜€λ²„λ‘œλ”©μ€ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€.

μ—°μ‚°μžμ˜ ν˜•νƒœλ‘œ μ‚¬μš©ν•˜λ €λ©΄, infix ν™•μž₯ ν•¨μˆ˜ λ˜λŠ” ν†±λ ˆλ²¨ ν•¨μˆ˜λ₯Ό ν™œμš©ν•˜λΌ.

Item 13 Unit?을 λ¦¬ν„΄ν•˜μ§€ 말라

기본적으둜 Unit? 을 λ¦¬ν„΄ν•˜κ±°λ‚˜, 이λ₯Ό 기반으둜 μ—°μ‚°ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€.

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

코틀린은 κ°œλ°œμžκ°€ νƒ€μž…μ„ μ§€μ •ν•˜μ§€ μ•Šμ•„λ„, νƒ€μž…μ„ μ§€μ •ν•΄μ„œ λ„£μ–΄ μ£ΌλŠ” ꡉμž₯히 μˆ˜μ€€ 높은 νƒ€μž… μΆ”λ‘  μ‹œμŠ€ν…œμ„ κ°–μΆ”κ³  μžˆλ‹€.

val num = 10
val name = "Marcin"
val dis = listOf(12, 112, 554, 997)

μœ„μ™€ 같은 μ½”λ“œλŠ” 개발 μ‹œκ°„μ„ 쀄여 쀄 뿐만 μ•„λ‹ˆλΌ, μœ ν˜•μ΄ λͺ…ν™•ν•  λ•Œ μ½”λ“œκ°€ μ§§μ•„μ§€λ―€λ‘œ μ½”λ“œμ˜ 가독성이 ν–₯μƒλœλ‹€.

μœ ν˜•μ΄ λͺ…ν™•ν•˜μ§€ μ•Šμ„ λ•ŒλŠ” λ‚¨μš©ν•˜λ©΄ 쒋지 μ•Šλ‹€.

val data = getSomeData()

가독성을 μœ„ν•΄ μ½”λ“œλ₯Ό 섀계할 λ•Œ μ½λŠ” μ‚¬λžŒμ—κ²Œ μ€‘μš”ν•œ 정보λ₯Ό μˆ¨κ²¨μ„œλŠ” μ•ˆλœλ‹€.

가독성 ν–₯상 μ΄μ™Έμ˜ μ•ˆμ „μ„ μœ„ν•΄μ„œλ„ νƒ€μž…μ„ μ§€μ •ν•˜λŠ” 것이 μ’‹λ‹€.

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

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

μŠ€μ½”ν”„ λ‚΄λΆ€μ˜ λ‘˜ μ΄μƒμ˜ λ¦¬μ‹œλ²„κ°€ μž‡λŠ” 경우, λͺ…μ‹œμ μœΌλ‘œ λ‚˜νƒ€λ‚΄λ©΄ μ’‹λ‹€.

class Node(val name: String) {
  fun makeChild(childName: String) = 
    create("$name.$childName")
      .apply { print("Created ${name}") }

  fun create(name: String): Node? = Node(name)
}

fun main() {
  val node = Node("parent")
  node.makeChild("child")         // Created parent
}
class Node(val name: String) {
        fun makeChild(childName: String) =
                create("$name.$childName")
                        .apply { print("Created ${this?.name} in ${this@Node.name}") }

        fun create(name: String): Node? = Node(name)
    }

fun main() {
  val node = Node("parent")
  node.makeChild("child")         // Created parent.child in parent
}

λ¦¬μ‹œλ²„λ₯Ό λͺ…ν™•ν•˜κ²Œ μž‘μ„±ν•˜λ©΄, μ½”λ“œλ₯Ό μ•ˆμ „ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆμ„ 뿐만 μ•„λ‹ˆλΌ 가독성도 ν–₯μƒλœλ‹€.

DSL 마컀

DSL λ§ˆμ»€λŠ” κ°€μž₯ κ°€κΉŒμš΄ λ¦¬μ‹œλ²„λ§Œμ„ μ‚¬μš©ν•˜κ±°λ‚˜, λͺ…μ‹œμ μœΌλ‘œ μ™ΈλΆ€ λ¦¬μ‹œλ²„λ₯Ό μ‚¬μš©ν•˜μ§€ λͺ»ν•˜κ²Œ ν•  λ•Œ ν™œμš©ν•  수 μžˆλŠ” ꡉμž₯히 μ€‘μš”ν•œ λ©”μ»€λ‹ˆμ¦˜μ΄λ‹€.

정리

μ—¬λŸ¬κ°œμ˜ λ¦¬μ‹œλ²„κ°€ μžˆλŠ” 상황 λ“±μ—μ„œλŠ” λ¦¬μ‹œλ²„λ₯Ό λͺ…μ‹œμ μœΌλ‘œ 적어 μ£ΌλŠ” 것이 μ’‹λ‹€.

λ¦¬μ‹œλ²„λ₯Ό λͺ…μ‹œμ μœΌλ‘œ 적게 κ°•μ œν•˜κ³  μ‹Άλ‹€λ©΄, @DslMarker 메타 μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•œλ‹€.

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

기본적으둜 ν”„λ‘œνΌν‹°λŠ” μ‚¬μš©μž μ •μ˜ Getter 와 Setter λ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.

val name: String? = null
  get() = field?.toUpperCase()
  set(value) {
    if (!value.isNullOrBlank()) {
      field = value
    }
  }

μœ„ μ½”λ“œμ˜ field μ‹λ³„μžλŠ” ν”„λ‘œνΌν‹°μ˜ 데이터λ₯Ό μ €μž₯ν•΄ λ‘λŠ” λ°±ν‚Ή ν•„λ“œ(backing field) 에 λŒ€ν•œ λ ˆνΌλŸ°μŠ€μ΄λ‹€.

읽기 μ „μš© ν”„λ‘œνΌν‹°λŠ” field κ°€ λ§Œλ“€μ–΄μ§€μ§€ μ•ŠλŠ”λ‹€.

val fullName: String
  get() = "$name $surname"

var 을 μ‚¬μš©ν•΄μ„œ λ§Œλ“  읽고 μ“Έ 수 μžˆλŠ” ν”„λ‘œνΌν‹°λŠ” κ²Œν„°μ™€ μ„Έν„°λ₯Ό μ •μ˜ν•  수 μžˆλ‹€.

이λ₯Ό νŒŒμƒ ν”„λ‘œνΌν‹°(derived property) 라고 λΆ€λ₯Έλ‹€.

μ›μΉ™μ μœΌλ‘œ ν”„λ‘œνΌν‹°λŠ” μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄κ±°λ‚˜ μ„€μ •ν•˜κΈ° μœ„ν•œ λͺ©μ μœΌλ‘œλ§Œ μ‚¬μš©ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— μ•„λž˜μ™€ 같이 λ‹€λ₯Έ λ‘œμ§μ„ ν¬ν•¨ν•˜μ§€ μ•Šμ•„μ•Ό ν•œλ‹€.

val Tree<Int>.sum: Int
  get() = when (this) {
    is Leaf -> value
    is Node -> left.sum + right.sum
  }

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

  • μ—°μ‚° λΉ„μš©μ΄ λ†’κ±°λ‚˜, λ³΅μž‘λ„κ°€ O(1) 보닀 큰 경우
    • ν•¨μˆ˜λ₯Ό ν™œμš©ν•˜μ—¬ μ‚¬μš©ν•œλ‹€λ©΄ μ‚¬μš©μžκ°€ μ—°μ‚°λΉ„μš©μ„ μ˜ˆμΈ‘ν•˜κΈ° 쉽고 이λ₯Ό κΈ°λ°˜μœΌλ‘œν•œ 캐싱등을 κ³ λ €ν•  수 μžˆλ‹€.
  • λΉ„μ§€λ‹ˆμŠ€ 둜직(μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λ™μž‘) 을 ν¬ν•¨ν•˜λŠ” 경우
    • ν”„λ‘œνΌν‹°λŠ” λ‹¨μˆœ λ™μž‘ 이상을 μˆ˜ν–‰ν•  것이라고 μ˜ˆμƒν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.
  • 결정적이지 μ•Šμ€ 경우
    • ν•¨μˆ˜μ˜ μ‹€ν–‰ μ‹œμ μ— λ‹€λ₯Έ 값을 λ‚˜μ˜€λŠ” 경우
  • λ³€ν™˜μ˜ 경우
    • ν•΄λ‹Ή ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•˜λŠ” μ‚¬μš©μžλ‘œ ν•˜μ—¬κΈˆ μ˜€ν•΄λ₯Ό 뢈러 μΌμœΌν‚¬ 수 μžˆλ‹€.
  • Getter μ—μ„œ ν”„λ‘œνΌν‹° μƒνƒœμ˜ 변경이 μΌμ–΄λ‚˜μ•Ό ν•˜λŠ” 경우
    • ν”„λ‘œνΌν‹°μ—μ„œ μƒνƒœλ³€ν™”λ₯Ό μΌμœΌν‚€κ²Œ 끔 κΈ°λŒ€ν•˜μ§€ μ•ŠλŠ”λ‹€

ν”„λ‘œνΌν‹°λŠ” μƒνƒœ 집합을 λ‚˜νƒ€λ‚΄κ³ , ν•¨μˆ˜λŠ” 행동을 λ‚˜νƒ€λ‚Έλ‹€.

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

νŒŒλΌλ―Έν„°κ°€ λͺ…ν™•ν•˜μ§€ μ•ŠλŠ” 경우 이λ₯Ό 직접 μ§€μ •ν•΄μ„œ λͺ…ν™•ν•˜κ²Œ λ§Œλ“€μ–΄ 쀄 수 μžˆλ‹€.

μ•„λž˜ μ½”λ“œμ²˜λŸΌ 이름 μžˆλŠ” μ•„κ·œλ¨ΌνŠΈ(named argument)λ₯Ό μ‚¬μš©ν•˜λΌ

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

λ˜ν•œ λ‹€μŒκ³Ό 같이 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 의미λ₯Ό λͺ…ν™•νžˆ ν•  수 μžˆλ‹€.

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

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

이름 μžˆλŠ” μ•„κ·œλ¨ΌνŠΈλ₯Ό μ‚¬μš©ν•˜λ©΄ μ½”λ“œκ°€ κΈΈμ–΄μ§€μ§€λ§Œ, λ‹€μŒκ³Ό 같은 μž₯점이 μžˆλ‹€.

  • 이름을 기반으둜 값이 무엇을 λ‚˜νƒ€λ‚΄λŠ”μ§€ μ•Œ 수 μžˆλ‹€.
  • νŒŒλΌλ―Έν„° μž…λ ₯ μˆœμ„œμ™€ 상관 μ—†μœΌλ―€λ‘œ μ•ˆμ „ν•˜λ‹€.

μ•„λž˜μ™€ 같이 100 κ°’μ˜ μ˜λ―Έκ°€ λͺ¨ν˜Έν•˜λ‹€.

sleep(100)

μ΄λ¦„μžˆλŠ” μ•„κ·œλ¨ΌνŠΈ μ‚¬μš©

sleep(timeMillis = 100)

ν•¨μˆ˜λ‘œ μ‹œκ°„λ‹¨μœ„λ₯Ό ν‘œν˜„

sleep(Millis(100))

ν™•μž₯ ν”„λ‘œνΌν‹°λ‘œ DSLκ³Ό μœ μ‚¬ν•œ 문법

sleep(100.ms)

μ΄λ¦„μžˆλŠ” μ•„κ·œλ¨ΌνŠΈλ₯Ό μ‚¬μš©ν•˜λŠ” 경우

  • λ””ν΄νŠΈ μ•„κ·œλ¨ΌνŠΈ 경우
  • 같은 νƒ€μž…μ˜ νŒŒλΌλ―Έν„°κ°€ λ§Žμ€ 경우
  • ν•¨μˆ˜ νƒ€μž…μ˜ νŒŒλΌλ―Έν„°κ°€ μžˆλŠ” 경우

λ””ν΄νŠΈ μ•„κ·œλ¨ΌνŠΈ 경우

ν”„λ‘œνΌν‹°κ°€ λ””ν΄νŠΈ μ•„κ·œλ¨ΌνŠΈλ₯Ό κ°€μ§ˆ 경우, 항상 이름을 λΆ™μ—¬μ„œ μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.

ν•¨μˆ˜ 이름은 ν•„μˆ˜ νŒŒλΌλ―Έν„°λ“€κ³Ό 관련이 있으며, λ””ν΄νŠΈ 값을 κ°–λŠ” μ˜΅μ…˜ νŒŒλΌλ―Έν„° (optional parameter) 의 μ„€λͺ…이 λͺ…ν™•ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, 이름을 λΆ™μ—¬μ„œ μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.

같은 νƒ€μž…μ˜ νŒŒλΌλ―Έν„°κ°€ λ§Žμ€ 경우

fun sendEmail(to: String, message: String) {
  /**
   * other codes
   **/
}

μœ„μ™€ 같이 ν•¨μˆ˜μ˜ 같은 데이터 νƒ€μž…μ˜ νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•  경우 이름 μžˆλŠ” μ•„κ·œλ¨ΌνŠΈλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.

sendEmail(
  to = "abc@google.com",
  message = "Hello, ..."
)

ν•¨μˆ˜ νƒ€μž… νŒŒλΌλ―Έν„°

일반적으둜 ν•¨μˆ˜ νƒ€μž… νŒŒλΌλ―Έν„°λŠ” λ§ˆμ§€λ§‰ μœ„μΉ˜μ— λ°°μΉ˜ν•˜λŠ” 것이 μ’‹λ‹€.

ν•¨μˆ˜ 이름이 μ•„κ·œλ¨ΌνŠΈλ₯Ό μ„€λͺ…ν•΄ 주기도 ν•œλ‹€.

λ‹€μŒκ³Ό 같이 repeat 인 경우 뒀에 μ˜€λŠ” λžŒλ‹€λŠ” 반볡될 λΈ”λŸ­μ„ λ‚˜νƒ€λ‚Έλ‹€.

repeat {
  /**
   * other codes
   **/
}

λ‹€μŒμ€ λ¦¬μ—‘ν‹°λΈŒ λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ 자주 λ³Ό 수 μžˆλŠ” ν˜•νƒœμ΄λ‹€.

RxJava μ—μ„œ Observable λ₯Ό ꡬ독할 λ•Œ ν•¨μˆ˜λ₯Ό μ„€μ •ν•œλ‹€.

  • 각각의 μ•„μ΄ν…œμ„ 받을 λ•Œ (onNext)
  • 였λ₯˜κ°€ λ°œμƒν–ˆμ„ λ•Œ (onError)
  • 전체가 μ™„λ£Œλ˜μ—ˆμ„ λ•Œ (onComplete)
observable.getuser()
  .subscribeBy {
    onNext = { user: List<User> -> 
      /**
       * other codes
       **/
    },
    onError = { throwable: Throwable ->
      /**
       * other codes
       **/
    },
    onCompleted = { 
      /**
       * other codes
       **/
    }
  }

정리

이름 μžˆλŠ” μ•„κ·œλ¨ΌνŠΈλŠ” κ°œλ°œμžκ°€ μ½”λ“œλ₯Ό 읽을 λ•Œλ„ νŽΈλ¦¬ν•˜κ²Œ ν™œμš©λ˜λ©°, μ•ˆμ •μ„±λ„ ν–₯μƒμ‹œν‚¬ 수 μžˆλ‹€.

Item 18 μ½”λ”© μ»¨λ²€μ…˜μ„ μ§€μΌœλΌ

μ½”λ”©μ»¨λ²€μ…˜μ„ 지킀면 λ‹€μŒκ³Ό 같은 이점이 μžˆλ‹€.

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

IDE μ—μ„œλŠ” μ—¬λŸ¬ ν”ŒλŸ¬κ·ΈμΈμ„ ν†΅ν•΄μ„œ 이λ₯Ό μ§€μ›ν•œλ‹€.

  • IntelliJ Formatter
  • ktlink

λ§Žμ€ νŒŒλΌλ―Έν„°λ₯Ό 가지고 μžˆλŠ” κ²½μš°μ—λŠ” λ‹€μŒκ³Ό 같이 ν•œμ€„μ”© μž‘μ„±ν•˜λŠ” 것을 ꢌμž₯ν•œλ‹€.

class Person(
  val id: Int = 0,
  val name: String = "",
  val surname: String = ""
): Human(id, name) {
  // λ³Έλ¬Έ
}

마치 ν•œ κ°œλ°œμžκ°€ μž‘μ„±ν•œ 것과 같이 μ½”λ”© μ»¨λ²€μ…˜μ„ μ€€μˆ˜ν•˜λ©΄ μ½”λ“œμ˜ μΌκ΄€μ„±μžˆλŠ” ν’ˆμ§ˆμ„ μœ μ§€ν•  수 μžˆλ‹€.