Chapter 5 κ°μ²΄ μμ±
μ½νλ¦°μ μ½λλ μμ ν¨μν μ€νμΌλ‘ μμ±ν μ μμ§λ§, μλ°μ²λΌ κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°(Object Oriented Programming, OOP) μ€νμΌλ‘λ μμ±ν μ μλ€.
OOPλ κ°μ²΄λ₯Ό μμ±ν΄μ μ¬μ©νλ―λ‘, κ°μ²΄λ₯Ό μμ±νλ λ°©λ²μ μ μν΄μΌ νκ³ , μ΄μ λν λ°©λ²λ€κ³Ό μ₯λ¨μ μ μ΄ν΄λ΄μΌ νλ€.
λν μ½νλ¦°μ μ μ λ©μλλ₯Ό μ¬μ©ν μ μλ€.
κ·Έλμ μΌλ°μ μΌλ‘ ν±λ 벨 ν¨μμ companion κ°μ²΄ ν¨μ λ±μ λμ νμ©νλ€.
μ΄λ€μ μλλ°©μμλ ν° μ°¨μ΄κ° μμΌλ―λ‘ μμ보λλ‘ νμ.
Item 33 μμ±μ λμ ν©ν 리 ν¨μλ₯Ό μ¬μ©νλΌ
ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό λ§λλ κ°μ₯ κΈ°λ³Έμ μΈ λ°©λ²μ κΈ°λ³Έ μμ±μ(primary constructor) λ₯Ό μ¬μ©νμ¬ λ§λλ λ°©λ²μ΄λ€.
class MyLinkedList<T>(
val head: T,
val tail: MyLinkedList<T>?
)
val list = MyLinkedList(1, MyLinkedList(2, null))
μμ±μκ° κ°μ²΄λ₯Ό λ§λ€ μ μλ μ μΌν λ°©λ²μ μλλ©°, λμμΈ ν¨ν΄ μ€ μμ± ν¨ν΄(creational pattern)μ μ΄μ©νμ¬ λ§λ€ μ μλ€.
μμ± ν¨ν΄μ κ°μ²΄λ₯Ό μμ±μλ‘ μ§μ μμ±νμ§ μκ³ , λ³λμ ν¨μλ₯Ό ν΅ν΄ μμ±νλ€.
fun <T> myLinkedListOf(
vararg elements: T
): MyLinkedList<T>? {
if (elements.isEmpty()) return null
val head = elements.first()
val elementsTail = elements.copyOfRange(1, elements.size)
val tail = myLinkedListOf(*elementsTail)
return MyLinkedList(head, tail)
}
val list = myLinkedListOf(1, 2)
κ°μ²΄ μΈμ€ν΄μ€ μμ±μ μν ν¨ν΄ μ€ ν©ν 리 λ©μλ ν΄λμ€μμ μμ±μμ μνμ λμ ν΄ μ£Όλ ν¨μλ₯Ό ν©ν 리 ν¨μλΌκ³ νλ€.
ν©ν 리 λ©μλλ₯Ό μ΄μ©νμ λμ λ€μκ³Ό κ°μ μ₯μ μ΄ μλ€.
- ν¨μμ μ΄λ¦μ λΆμΌμ μλ€
- μμ±μλ₯Ό μ΄μ©νμ¬ μμ±νλκ² λ³΄λ€ ν¨μ¬ μ΄ν΄νκΈ° μ½λ€.(
ArrayList.withSize(3)
) - λμΌν νλΌλ―Έν° νμ μ κ°λ μμ±μμ μΆ©λμ μ€μΌ μ μλ€.
- μμ±μλ₯Ό μ΄μ©νμ¬ μμ±νλκ² λ³΄λ€ ν¨μ¬ μ΄ν΄νκΈ° μ½λ€.(
- μνλ νμ
μ κ°μ²΄λ₯Ό 리ν΄ν μ μλ€.
- μμ±μμ λ€λ₯΄κ² ν¨μκ° μνλ ννμ νμ μ 리ν΄ν μ μλ€.
- κ°μ²΄ μμ±μ λ°λ₯Έ μ λ΅μ μΈμΈ μ μλ€.
- μμ±μμ λ€λ₯΄κ² νΈμΆλ λλ§λ€ μ κ°μ²΄λ₯Ό λ§λ€ νμκ° μλ€.
- μ±κΈν΄ ν¨ν΄μ²λΌ κ°μ²΄λ₯Ό νλλ§ μμ±νκ² κ°μ νκ±°λ, μ΅μ νλ₯Ό μν΄ μΊμ± λ©μ»€λμ¦μ μ¬μ©ν μ μλ€.
- κ°μ²΄λ₯Ό λ§λ€ μ μμ κ²½μ°
null
μ 리ν΄νκ² λ§λ€ μ μλ€.
- ν©ν 리 ν¨μλ μμ§ μ‘΄μ¬νμ§ μλ κ°μ²΄λ₯Ό 리ν΄ν μ μλ€.
- νλ‘μ νΈλ₯Ό λΉλνμ§ μκ³ μμΌλ‘ λ§λ€μ΄μ§ κ°μ²΄λ₯Ό μ¬μ©ν μ μλ€.
- νλ‘μλ₯Ό ν΅ν΄ λ§λ€μ΄μ§λ κ°μ²΄λ₯Ό μ¬μ©ν μ μλ€.
- κ°μ²΄ μΈλΆμ ν©ν 리 ν¨μλ₯Ό λ§λ€λ©΄, κ·Έ κ°μμ±μ μνλλλ‘ μ μ΄ν μ μλ€.
- ν©ν 리 ν¨μλ μΈλΌμΈμΌλ‘ λ§λ€μ μμΌλ©°, κ·Έ νλΌλ―Έν°λ₯Ό
reified
λ‘ λ§λ€μ μλ€. - ν©ν 리 ν¨μλ μμ±μλ‘ λ§λ€κΈ° 볡μ‘ν κ°μ²΄λ μμ±μ΄ κ°λ₯νλ€.
- μ¬μ©μκ° μνλ μμ μ κ°μ²΄λ₯Ό λ§λ€μ μλ€.
ν©ν 리 ν¨μ λ΄λΆμμλ μμ±μλ₯Ό μ΄μ©νμ¬ μ¬μ©ν΄μΌ νλ€.
ν©ν 리 ν¨μλ κΈ°λ³Έ μμ±μκ° μλ μΆκ° μμ±μ(secondary constructor) μ κ²½μκ΄κ³ μ΄λ€.
Companion κ°μ²΄ ν©ν 리 ν¨μ
ν©ν 리 ν¨μλ₯Ό μ μνλ κ°μ₯ μΌλ°μ μΈ λ°©λ²μ companion κ°μ²΄λ₯Ό μ¬μ©νλ κ²μ΄λ€.
class MyLinkedList<T>(
val head: T,
val tail: MyLinkedList<T>?
) {
companion object {
fun <T> of(vararg elements: T): MyLinkedList<T>? {
/*...*/
}
}
}
val list = MyLinkedList.of(1, 2)
μ΄λ¬ν λ°©λ²μ μΈν°νμ΄μ€μλ ꡬνν μ μλ€.
class MyLinkedList<T>(
val head: T,
val tail: MyLinkedList<T>?
): MyList<T> {
//...
}
interface MyList<T> {
//...
companion object {
fun <T> of(vararg elements: T): MyList<T>? {
//...
}
}
}
val list = MyList.of(1, 2)
ν©ν 리 ν¨μμμλ λ€μκ³Ό κ°μ μ΄λ¦μ΄ μ£Όλ‘ μ¬μ©λλ€.
from: νλΌλ―Έν°λ₯Ό νλ λ°κ³ κ°μ νμ μ μΈμ€ν΄μ€ νλλ₯Ό 리ν΄νλ λ³ν ν¨μ
val date: Date = Date.from(instant)
of: νλΌλ―Έν°λ₯Ό μ¬λ €κ° λ°κ³ , μ΄λ₯Ό ν΅ν©ν΄μ μΈμ€ν΄μ€λ₯Ό λ§λ€μ΄ μ£Όλ ν¨μ
val faceCards = Set<Rank> = EnumSet.of(JACK, QUEEN, KING)
valueOf: from λλ ofμ λΉμ·ν κΈ°λ₯μ νλ©΄μλ, μλ―Έλ₯Ό μ‘°κΈ λ μ½κ² μ½μμ μκ² μ΄λ¦μ λΆμΈ ν¨μ
val prime: BigInteger = BigInteger.valueOf(Integer.MAX_VALUE)
instance/getInstance: μ±κΈν΄μΌλ‘ νλμ μΈμ€ν΄μ€λ₯Ό 리ν΄νλ ν¨μ
val luke: StackWalker = StackWalker.getInstance(options)
createdInstance/newInstance: instance/getInstance μ²λΌ λμ νμ§λ§ ν¨μλ₯Ό νΈμΆν λλ§λ€ μλ‘μ΄ μΈμ€ν΄μ€λ₯Ό λ§λ€μ΄μ 리ν΄
val newArray = Array.newInstance(classObject, arrayLen)
getType: instance/getInstance μ²λΌ λμνμ§λ§ ν©ν 리 ν¨μκ° λ€λ₯Έ ν΄λμ€μ μμλ μ¬μ©νλ©°, νμ μ ν©ν 리 ν¨μμμ 리ν΄νλ νμ
val fs: FileStore = Files.getFileStore(path)
newType: createdInstance/newInstance μ²λΌ λμνμ§λ§ ν©ν 리 ν¨μκ° λ€λ₯Έ ν΄λμ€μ μμλ μ¬μ©νλ©°, νμ μ ν©ν 리 ν¨μμμ 리ν΄νλ νμ
val br: BufferedReader = Files.newBufferedReader(path)
κ²½νμ΄ μλ μ½νλ¦° κ°λ°μλ€μ companion κ°μ²΄ λ©€λ²λ₯Ό λ¨μν μ μ λ©€λ²μ²λΌ λ€λ£¨λ κ²½μ°κ° λ§λ€.
νμ§λ§ companion κ°μ²΄λ λ λ§μ κΈ°λ₯μ κ°μ§κ³ μμΌλ©°, companion κ°μ²΄λ μΈν°νμ΄μ€λ₯Ό ꡬνν μ μκ³ , ν΄λμ€λ₯Ό μμλ°μ μλ μλ€.
μλ₯Ό λ€μ΄ μ½νλ¦°μ μ½λ£¨ν΄ λ΄λΆμμλ μ½λ£¨ν΄ 컨ν
μ€νΈμ companion κ°μ²΄λ€μ΄ CoroutineContext.Key
μΈν°νμ΄μ€λ₯Ό ꡬννκ³ μλ€.
public interface ContinuationInterceptor : CoroutineContext.Element {
/**
* The key that defines *the* context interceptor.
*/
companion object Key : CoroutineContext.Key<ContinuationInterceptor>
}
νμ₯ ν©ν 리 ν¨μ
μ΄λ―Έ companion κ°μ²΄κ° μ‘΄μ¬ν λ, μ΄ companion κ°μ²΄λ₯Ό μ§μ μμ ν μλ μκ³ , λ€λ₯Έ νμΌμ ν¨μλ₯Ό λ§λ€μ΄μΌ ν λ μ¬μ©νλ€.
λ€μκ³Ό κ°μ΄ Tool μΈν°νμ΄μ€λ₯Ό κ΅μ²΄ν μ μλ€κ³ κ°μ ν΄λ³΄μ
interface Tool {
companion object { /*...*/ }
}
companion κ°μ²΄λ₯Ό νμ©ν΄μ νμ₯ ν¨μλ₯Ό μ μν μ μλ€.
fun Tool.Companion.createBigTool(/*...*/): BigTool {
//...
}
// μ¬μ©
Tool.createBigTool()
ν±λ 벨 ν©ν 리 ν¨μ
κ°μ²΄λ₯Ό λ§λλ λ°©λ² μ€ νλλ‘ listOf
, setOf
, mapOf
λ±κ³Ό κ°μ ν±λ 벨 ν©ν 리 ν¨μλ₯Ό μ΄μ©νλ λ°©λ²μ΄ μλ€.
ν±λ 벨 ν¨μλ κ΅μ₯ν κ΄λ²μνκ² μ¬μ©νμ§λ§ public ν±λ 벨 ν¨μλ λͺ¨λ κ³³μμ μ¬μ©ν μ μμΌλ―λ‘ IDEμ νμ 볡μ‘νκ² λ§λλ λ¨μ μ΄ μλ€.
λ°λΌμ ν±λ 벨 ν¨μλ₯Ό λ§λ€ λλ μ΄λ¦μ μ μ€νκ² μ μ§μ ν΄μΌ νλ€.
κ°μ§ μμ±μ
μΌλ°μ μΈ μ½νλ¦°μ μμ±μλ ν±λ 벨 ν¨μμ κ°μ ννλ‘ μ¬μ©λλ€.
class A
val a = A()
μΌλ°μ μΈ κ΄μ μμ λλ¬Έμλ‘ μμνλμ§ μλμ§λ μμ±μμ ν¨μλ₯Ό ꡬλΆνλ κΈ°μ€μ΄ λκΈ°λ νλ€.
ν¨μλ λλ¬Έμλ‘ μμλ μ μμ§λ§, μ΄λ νΉμν λ€λ₯Έ μ©λλ‘ μ¬μ©λλ€.
public inline fun <T> List(
size: Int,
init: (index: Int) -> T
): List<T> = MutableList(size, init)
public inline fun <T> MutableList(
size: Int,
init: (index: Int) -> T
): MutableList<T> {
val list = ArrayList<T>(size)
repeat(size) { index -> list.add(init(index))}
return list
}
μμ κ°μ ν±λ 벨 ν¨μλ μμ±μμ²λΌ 보μ΄κ³ , μμ±μμ²λΌ λμλλ€.
νμ§λ§ ν©ν 리 ν¨μμ κ°μ λͺ¨λ μ₯μ μ κ°λλ€.
λ§μ μ½νλ¦° κ°λ°μκ° μ΄λ₯Ό ν±λ 벨 ν¨μμΈμ§ μ λͺ°λ₯΄λ©°, μ΄λ₯Ό κ°μ§ μμ±μ(fake constructor) λΌκ³ λΆλ₯Έλ€.
κ°μ§ μμ±μλ₯Ό λ§λλ μ΄μ λ λ€μκ³Ό κ°λ€.
- μΈν°νμ΄μ€λ₯Ό μν μμ±μλ₯Ό λ§λ€κ³ μΆμλ
- refried νμ μκ·λ¨ΌνΈλ₯Ό μκ²νκ³ μΆμλ
κ°μ§ μμ±μλ μ§μ§ μμ±μμ²λΌ λμλμ΄μΌ νλ©° μ§μ§ μμ±μμ κ°μ λμμ ν΄μΌ νλ€.
κ°μ§ μμ±μλ₯Ό μ μΈνλ λ λ€λ₯Έ λ°©λ²μ invoke
μ°μ°μλ₯Ό κ°λ companion κ°μ²΄λ₯Ό μ¬μ©νλ©΄ λΉμ·ν κ²°κ³Όλ₯Ό μ»μ μ μλ€.
class Tree<T> {
companion object {
operator fun <T> invoke(size: Int, generator: (Int) -> T): Tree<T> {
//...
}
}
}
// μ¬μ©
Tree(10) { "$it" }
μ΄μ κ°μ λ°©μμ κ±°μ μ¬μ©λμ§ μμΌλ©° κΆμ₯νμ§ μλλ€.
ν©ν 리 ν΄λμ€μ λ©μλ
ν©ν 리 ν΄λμ€μ κ΄λ ¨λ μΆμ ν©ν 리, νλ‘ν νμ λ±μ μλ§μ μμ± ν¨ν΄μ΄ μλ€.
μ΄λ° ν¨ν΄ μ€ μΌλΆλ μ½νλ¦°μμλ μ ν©νμ§ μμΌλ©°, μΌλΆ ν¨ν΄(μ μΈ΅μ μμ±μ ν¨ν΄, λΉλ ν¨ν΄)μ μ½νλ¦°μμλ μλ―Έκ° μλ€.
data class Student(
val id: Int,
val name: String,
val surname: String
)
class StudentsFactory {
var nextId = 0
fun next(name: String, surname: String) = Student(nextId++, name, surname)
}
val factory = StudentsFactory()
val s1 = factory.next("Marcin", "Moskala")
println(s1) // Student(id=0, name=Marcin, Surname=Moskala)
val s2 = factory.next("Igor", "Wojda")
println(s2) // Student(id=1, name=Igor, Surname=Wojda)
ν©ν 리 ν΄λμ€λ νλ‘νΌν°λ₯Ό κ°μ§ μ μκ³ , μ΄λ₯Ό νμ©νλ©΄ λ€μν μ’ λ₯λ‘ μ΅μ ν νκ±°λ κΈ°λ₯μ λμ ν μ μλ€.
μ 리
μ½νλ¦°μ ν©ν 리 ν¨μλ₯Ό λ§λ€ μ μλ λ€μν λ°©λ²λ€μ μ 곡νλ©° κ°κ°μ λ°©λ²λ€μ μ¬λ¬ νΉμ§μ κ°κ³ μλ€.
κ°μ²΄λ₯Ό μμ±ν λλ μ΄λ° νΉμ§μ μ νμ νκ³ μ¬μ©ν΄μΌ νλ©°, ν©ν 리 ν¨μλ₯Ό μ¬μ©νλ κ°μ₯ μΌλ°μ μΈ λ°©λ²μ companion κ°μ²΄λ₯Ό νμ©νλ κ²μ΄λ€.
Item 34 κΈ°λ³Έ μμ±μμ μ΄λ¦ μλ μ΅μ μκ·λ¨ΌνΈλ₯Ό μ¬μ©νλΌ
κ°μ²΄λ₯Ό μ μνκ³ μμ±νλ λ°©λ²μ μ§μ ν λ μ¬μ©νλ κ°μ₯ κΈ°λ³Έμ μΈ λ°©λ²μ κΈ°λ³Έ μμ±μ(primary constructor)λ₯Ό μ¬μ©νλ κ²μ΄λ€.
class User(var name: String, var surname: String)
val user = User("Blue", "Berry")
κΈ°λ³Έ μμ±μλ‘ κ°μ²΄λ₯Ό λ§λ€ λλ κ°μ²΄μ μ΄κΈ° μνλ₯Ό λνλ΄λ μκ·λ¨ΌνΈλ€μ μ λ¬νλ€.
data class Student(
val name: String,
val surname: String,
val age: Int
)
λ€μ μλ μΈλ±μ€κ° λΆμ΄ μλ κΈμ μΆλ ₯νλ νλ μ ν° κ°μ²΄μ΄λ€.
μ΄ κ°μ²΄λ κΈ°λ³Έ μμ±μλ₯Ό μ¬μ©ν΄μ μ’ μμ±μ μ£Όμ ν μ μλ€.
class QuotationPresenter(
private val view: QuotationView,
private val repo: QuotationRepository
) {
private var nextQuoteId = -1
fun onStart() {
onNext()
}
fun onNext() {
nextQuoteId = (nextQuoteId + 1) % repo.quotesNumber
val quote = repo.getQuote(nextQuoteId)
view.showQuote(quote)
}
}
QuotationPresenter
λ κΈ°λ³Έ μμ±μμ μ μΈλμ΄ μλ νλ‘νΌν°λ³΄λ€ λ λ§μ νλ‘νΌν°λ₯Ό κ°κ³ μλ€.
μ μ½λμμ nextQuoteId
νλ‘νΌν°λ νμ -1 λ‘ μ΄κΈ°ν λλ€.
κΈ°λ³Έ μμ±μκ° μ’μ μ΄μ λ₯Ό μ€λͺ νκΈ° μν΄ λ€μ λκΈ°μ§ μμλ₯Ό μ΄ν΄λ³Έλ€.
μ μ¦μ μμ±μ ν¨ν΄
μ μ¦μ μμ±μ ν¨ν΄μ μ¬λ¬κ°μ§ μ’ λ₯μ μμ±μλ₯Ό μ¬μ©νλ κ΅μ₯ν κ°λ¨ν ν¨ν΄μ΄λ€.
class Pizza {
val size: String
val cheese: Int
val olives: Int
val bacon: Int
β
constructor(size: String, cheess: Int, olives: Int, bacon: Int) {
this.size = size
this.cheess = cheess
this.olives = olives
this.bacon = bacon
}
constructor(size: String, cheese: Int, olives: Int): this(size, cheese, olives, 0)
constructor(size: String, cheese: Int): this(size, cheese, 0)
constructor(size: String): this(size, 0)
}
μ μ½λλ μ’μ μ½λκ° μλλ€.
μ½νλ¦°μμλ μΌλ°μ μΌλ‘ μλμ κ°μ΄ λν΄νΈ μκ·λ¨ΌνΈ(default argument)λ₯Ό μ¬μ©νλ€.
class Pizza(
val size: String,
val cheese: Int = 0,
val olives: Int = 0,
val bacon: Int = 0
)
μμ κ°μ λν΄νΈ μκ·λ¨ΌνΈλ μ½λλ₯Ό λ¨μνκ³ κΉλνκ² λ§λ€μ΄μ€ λΏλ§ μλλΌ λ€μν κΈ°λ₯λ μ 곡νλ€.
- νλΌλ―Έν°λ€μ κ°μ μνλ λλ‘ μ§μ ν μ μλ€.
- μκ·λ¨ΌνΈλ₯Ό μνλ μμλ‘ μ§μ ν μ μλ€.
- λͺ μμ μΌλ‘ μ΄λ¦μ λΆμ¬μ μκ·λ¨ΌνΈλ₯Ό μ§μ νλ―λ‘ μλ―Έκ° ν¨μ¬ λͺ ννλ€.
μ΄λ¦ μλ μκ·λ¨ΌνΈ(named argument)λ₯Ό νμ©νμ¬ λͺ μμ μΌλ‘ μ΄λ¦μ λΆμ¬μ£Όμ΄ μλ―Έκ° λͺ νν΄μ§λ€.
λΉλ ν¨ν΄
μλ°μμλ μ΄λ¦ μλ μκ·λ¨ΌνΈμ λν΄νΈ μκ·λ¨ΌνΈλ₯Ό μ¬μ©ν μ μμ§λ§ λΉλ ν¨ν΄μ μ¬μ©νλ€.
μλ°μ λΉλ ν¨ν΄μ μλμ κ°μ μ₯μ μ μ 곡νλ€.
- νλΌλ―Έν°μ μ΄λ¦μ λΆμΌ μ μλ€.
- νλΌλ―Έν°λ₯Ό μνλ μμλλ‘ μ§μ ν μ μλ€.
- λν΄νΈ κ°μ μ§μ ν μ μλ€.
λΉλ ν¨ν΄μ μ½νλ¦°μΌλ‘ λ§λ€μ΄λ³΄λ©΄ λ€μκ³Ό κ°μ΄ μμ±ν μ μλ€.
class Pizza private constructor(
val size: String,
val cheese: Int,
val olives: Int,
val bacon: Int
) {
class Builder(private val size: String) {
private var cheese: Int = 0
private var olives: Int = 0
private var bacon: Int = 0
fun setCheese(value: Int): Builder = apply {
cheese = value
}
fun setOlives(value: Int): Builder = apply {
olives = value
}
fun setBacon(value: Int): Builder = apply {
bacon = value
}
fun build() = Pizza(size, cheese, olives, bacon)
}
}
λΉλ ν¨ν΄μ μ¬μ©νλ©΄ λν΄νΈ μκ·λ¨ΌνΈλ₯Ό μ¬μ©νλκ²κ³Ό κ°μ ν¨κ³Όλ₯Ό λ³Ό μ μλ€.
νμ§λ§ λΉλν¨ν΄μ μ¬μ©νλκ² λ³΄λ€ μ΄λ¦ μλ μκ·λ¨ΌνΈλ₯Ό μ¬μ©νλκ²μ΄ λ μ’μ μ΄μ λ λ€μκ³Ό κ°λ€.
- λ 짧λ€
- λ λͺ ννλ€
- λ μ¬μ©νκΈ° μ½λ€
- λμμ±κ³Ό κ΄λ ¨λ λ¬Έμ κ° μλ€
- μ½νλ¦°μ ν¨μ νλΌλ―Έν°λ νμ immutable μ΄μ§λ§ λλΆλΆμ λΉλ ν¨ν΄μ mutable μ΄λ€
- λ°λΌμ λΉλ ν¨ν΄μ ν¨μλ₯Ό thread-safe νκ² κ΅¬ννλ κ²μ κΉλ€λ‘μ΄ μΌμ΄λ€
λ€λ§ λΉλ ν¨ν΄μ΄ λ μ μ©ν κ²½μ°λ μλ€.
κ°μ μλ―Έλ₯Ό λ¬Άμ΄μ μ§μ ν΄μΌ νλ κ²½μ°
val dialog = AlertDialog.Builder(context) .setMessage(R.string.fire_missiles) .setPositiveButton(R.string.fire, { d, id -> // λ―Έμ¬μΌ λ°μ¬! }) .setNegativeButton(R.string.cancel, { d, id -> // μ¬μ©μκ° λνμμμμ μ·¨μλ₯Ό λλ₯Έ κ²½μ° }) .create()
νΉμ κ°μ λμ ννλ‘ μ¬μ©ν΄μΌ νλ κ²½μ°
val router = Router.Builder() .addRoute(path = "/home", ::showHome) .addRoute(path = "/users", ::showUsers) .build()
μμ κ°μ κ²½μ°μ λΉλν¨ν΄μ λ§λ€μ§ μκ³ μΆκ°μ μΈ νμ μ λ§λ€κ³ νμ©νλ©΄ μ€νλ € λ 볡μ‘ν΄μ§μμλ€.
νμ§λ§ μ΄λ° νΉμν κ²½μ°λΌλ©΄ DSL(Domain Specific Language) λΉλλ₯Ό μ¬μ©ν΄μ ꡬννκΈ°λ νλ€.
μ 리
μΌλ°μ μΈ νλ‘μ νΈμμ κΈ°λ³Έ μμ±μλ₯Ό μ¬μ©ν΄ κ°μ²΄λ₯Ό λ§λ λ€.
μ½νλ¦°μμλ μ μΈ΅μ μμ±μ ν¨ν΄μ μ¬μ©νμ§ μλλ€.
λμ λν΄νΈ μκ·λ¨ΌνΈλ₯Ό νμ©νμ¬ μ¬μ©νλκ²μ΄ λ μ’λ€.
λν΄νΈ μκ·λ¨ΌνΈλ λ μ§§κ³ , λ λͺ ννκ³ , λ μ¬μ©νκΈ° μ½λ€.
Item 35 볡μ‘ν κ°μ²΄λ₯Ό μμ±νκΈ° μν DSLμ μ μνλΌ
μ½νλ¦°μ νμ©νλ©΄ DSL(Domain Specific Language)μ μ§μ λ§λ€ μ μλ€.
μ΄λ 볡μ‘ν κ°μ²΄, κ³μΈ΅ ꡬ쑰λ₯Ό κ°κ³ μλ κ°μ²΄λ€μ μ μν λ κ΅μ₯ν μ μ©νλ€.
DSL μ λ§λλ μΌμ νλ μΌμ΄μ§λ§, ν λ² λ§λ€κ³ λλ©΄ 보μΌλ¬νλ μ΄νΈ(boilerplate)μ 볡μ‘μ±μ μ¨κΈ°λ©΄μ κ°λ°μμ μλλ₯Ό λͺ ννκ² νν κ°λ₯νλ€.
μ¬μ©μ μ μ DSL λ§λ€κΈ°
μ¬μ©μ μ μ DSLμ λ§λλ λ°©λ²μ μ΄ν΄νλ €λ©΄, 리μλ²λ₯Ό μ¬μ©νλ ν¨μ νμ μ λν κ°λ μ μ΄ν΄ν΄μΌ νλ€.
μ± μ°Έκ³
μΈμ μ¬μ©ν΄μΌ ν κΉ?
DSL μ μ 보λ₯Ό μ μνλ λ°©λ²μ μ 곡νλ€.
- 볡μ‘ν μλ£ κ΅¬μ‘°
- κ³μΈ΅μ μΈ κ΅¬μ‘°
- κ±°λν μμ λ°μ΄ν°
λ§μ΄ μ¬μ©λλ λ°λ³΅λλ μ½λκ° μκ³ , μ΄λ₯Ό κ°λ¨νκ² λ§λ€ μ μλ λ³λμ μ½νλ¦° κΈ°λ₯μ΄λ λΌμ΄λΈλ¬λ¦¬κ° μλ€λ©΄ DSL μ¬μ©μ κ³ λ €ν΄λ³΄μλ μ’μκ² κ°λ€.
μ 리
DSLμ μΈμ΄ λ΄λΆμμ μ¬μ©ν μ μλ νΉλ²Όν μΈμ΄μ΄λ€.
볡μ‘ν κ°μ²΄λ λ¬Όλ‘ HTML μ½λ, 볡μ‘ν μ€μ λ±μ κ³μΈ΅κ΅¬μ‘°λ₯Ό κ°λ κ°μ²΄λ₯Ό κ°λ¨νκ² ννν μ μκ² ν΄μ€λ€.
μ μ μλ DSLμ νλ‘μ νΈμ κ΅μ₯ν ν° λμμ μ£Όμ§λ§, μ’μ DSLμ λ§λλ μμ μ κ΅μ₯ν νμ΄ λ λ€.