Tutorial/tutorial

[Kotlin] μ½”ν‹€λ¦° Property μœ„μž„

λŽμš” 2022. 9. 27. 17:01

μ•ˆλ…•ν•˜μ„Έμš”

μ˜€λŠ˜μ€ Kotlin ν”„λ‘œνΌν‹° μœ„μž„μ— λŒ€ν•΄ 

κ³΅λΆ€ν•œ λ‚΄μš©μ„ 정리해보렀 ν•©λ‹ˆλ‹€.

ν”„λ‘œνΌν‹° μœ„μž„μ΄λž€?

ν”„λ‘œνΌν‹°μ˜ κ°’ μ„€μ •(set)/κ°€μ Έμ˜€κΈ°(get)λ₯Ό λ‹€λ₯Έ class 및 λ©”μ†Œλ“œλ₯Ό 톡해 μœ„μž„ν•˜λ„λ‘ ν•˜λŠ” λ™μž‘μœΌλ‘œ

 

λ’·λ°›μΉ¨ ν•„λ“œ(Backing field)와 λ§ˆμ°¬κ°€μ§€λ‘œ

- val 의 경우 : getValue()만 κ΅¬ν˜„

- var 의 경우 : setValue() / getValue() λ‘˜λ‹€ κ΅¬ν˜„

 

by ν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ μœ„μž„ν•  객체λ₯Ό ν”„λ‘œνΌν‹° 뒀에 λͺ…μ‹œν•©λ‹ˆλ‹€.

μ•„μšΈλŸ¬ μœ„μž„ν•  getValue()와 setValue()λŠ” operator ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜„ν•©λ‹ˆλ‹€.

예제 μ½”λ“œλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

 

import kotlin.reflect.KProperty

data class Customer(val id: Int = -1, val name: String = "", var address: String = "", var phone: String = "")

val dataBase = mutableSetOf(
    Customer(1, "μœ μ €1", "μ„œμšΈμ‹œ 금천ꡬ", "010-3745-2833"),
    Customer(2, "μœ μ €2", "μ„œμšΈμ‹œ 노원ꡬ", "010-3745-2323"),
    Customer(3, "μœ μ €3", "μ„œμšΈμ‹œ 금천ꡬ", "010-3745-3278"),
    Customer(4, "μœ μ €4", "경기도 ν‰μ΄Œμ‹œ", "010-3745-2454")
)

/* getValue 에 λŒ€μ‘ν•˜λŠ” ν•¨μˆ˜ */
fun queryForCustomer(id: Int) = dataBase.find { customer ->
    customer.id == id
} ?: Customer(-1, "μžλ£Œμ—†μŒ", "μžλ£Œμ—†μŒ", "μžλ£Œμ—†μŒ")

/* setValue 에 λŒ€μ‘ν•˜λŠ” ν•¨μˆ˜ */
fun updateForCustomer(customer: Customer) = dataBase.add(customer)

/*
id λ₯Ό μ΄μš©ν•˜μ—¬ DB(μ—¬κΈ°μ„  κ°„λ‹¨ν•œ λ°°μ—΄)μ—μ„œ Customer 객체λ₯Ό
getter/setter λ₯Ό μœ„μž„(PersonDelegate)ν•˜μ—¬ 처리
*/
class PersonKT {
    var id : Int = -1
    var customerInfo: Customer by PersonDelegate()
}

class PersonDelegate{

    operator fun getValue(personKT: PersonKT, property: KProperty<*>): Customer {
        return queryForCustomer(personKT.id)
    }

    operator fun setValue(personKT: PersonKT, property: KProperty<*>, value: Customer) {
        if(updateForCustomer(value)){
            println("정상 μž…λ ₯!")
        }else{
            println("μž…λ ₯ μ‹€νŒ¨!")
        }
    }

}
fun main() {
    val personKT = PersonKT()
    personKT.customerInfo = Customer(5, "μœ μ €5", "μ„œμšΈμ‹œ 강남ꡬ", "010-3214-5678")
    personKT.id = 5 //setter ν˜ΈμΆœν•  λ•Œ μœ„μž„μ΄ μΌμ–΄λ‚˜ μž…λ ₯
    println(personKT.customerInfo) //getter 호좜 μ‹œ μœ„μž„ν•˜μ—¬ μ‹€ν–‰

}

 

 

μΆ”κ°€μ μœΌλ‘œ kotlin.property.observable을 ν†΅ν•œ μœ„μž„λ„ κ°€λŠ₯ν•œλ°

ν•΄λ‹Ή ν•¨μˆ˜λŠ” 값이 λ³€κ²½λ˜λŠ” 것을 κ΄€μ°°ν•˜μ—¬ λ™μž‘μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

μ½”λ“œλ₯Ό 보며 λ‹€μ‹œ μ„€λͺ…λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€. 

 

var monthOfSalary : Long by Delegates.observable(1L) 
     { _ , oldValue , newValue ->
        val mSalary = salary/12 - salary/12* TAX_RATE

        val previousSalary = when(oldValue){
            3L , 6L , 9L , 12L -> (mSalary + mSalary*0.5).toLong()
            else -> mSalary.toLong()
        }

        val currentSalary = when (newValue) {
            3L, 6L, 9L, 12L -> {
                (mSalary + mSalary*0.5).toLong()
            }
            else -> mSalary.toLong()
        }

        println("${oldValue}μ›”μ˜ κΈ‰μ—¬λŠ” ${NumberFormat.getCurrencyInstance().format(previousSalary)}이고 ${newValue}μ›”μ˜ κΈ‰μ—¬λŠ” $" +
                "${NumberFormat.getCurrencyInstance().format(currentSalary)}μž…λ‹ˆλ‹€.")
    }

 

μœ„μ™€ 같이 Delgate.observable을 λžŒλ‹€λ₯Ό 톡해 κ΅¬ν˜„ν•©λ‹ˆλ‹€. 

νŒŒλΌλ―Έν„°λŠ” μ΄ˆκΈ°κ°’μ„ λ‚˜νƒ€λ‚΄λ©°

λžŒλ‹€ ν•¨μˆ˜ κ΅¬ν˜„λΆ€μ—μ„œ μ „λ‹¬ν•΄μ£ΌλŠ” μΈμžκ°’μ€ 각각 Kproperty<*> , oldValue(이전 κ°’) , newValue(λ³€κ²½λœ κ°’)으둜 

μ‚¬μš©ν•˜μ§€ μ•Šμ„ 값은 ( _ ) 둜 μƒλž΅μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

μœ„ μ½”λ“œλŠ” 3,6,9,12 월은 λ³΄λ„ˆμŠ€λ₯Ό λ°›λŠ” λ‹€λŠ” κ°€μ •ν•˜μ— μ›”κΈ‰ (monthOfSalary)을 Delgate.observable에 μœ„μž„

ν•˜μ—¬ κ³„μ‚°ν•˜λ„λ‘ ν•˜λŠ” λΆ€λΆ„μž…λ‹ˆλ‹€. πŸ€”

 

μœ„ μ½”λ“œλ₯Ό μ‘μš©ν•˜μ—¬ 1~12μ›” 전체 월급을 좜λ ₯ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€μ–΄ λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

import java.text.NumberFormat
import java.time.format.FormatStyle
import java.util.*
import kotlin.math.abs
import kotlin.properties.Delegates


class EmployeeKT(val empName : String , private val salary : Long = 0L , val department : String = "κ°œλ°œλΆ€" , var empNumber : String = "") {
    
    var monthOfSalary : Long by Delegates.observable(1L)// νŒŒλΌλ―Έν„°λŠ” μ΄ˆκΈ°κ°’
    { _ , oldValue , newValue ->
        val mSalary = salary/12 - salary/12* TAX_RATE

        val previousSalary = when(oldValue){ // 이전달 μ›”κΈ‰
            3L , 6L , 9L , 12L -> (mSalary + mSalary*0.5).toLong()
            else -> mSalary.toLong()
        }

        val currentSalary = when (newValue) { // μ΄λ²ˆλ‹¬ μ›”κΈ‰
            3L, 6L, 9L, 12L -> {
                (mSalary + mSalary*0.5).toLong()
            }
            else -> mSalary.toLong()
        }

        println("${oldValue}μ›”μ˜ κΈ‰μ—¬λŠ” ${NumberFormat.getCurrencyInstance().format(previousSalary)}이고 ${newValue}μ›”μ˜ κΈ‰μ—¬λŠ” $" +
                "${NumberFormat.getCurrencyInstance().format(currentSalary)}μž…λ‹ˆλ‹€.")
    }

    init {
        empNumber = abs(Random().nextInt()).toString()
    }
}

fun main() {
    val emp = EmployeeKT("Lee Yo han" , 120_000_000)
    for(i in 2..12) {
        emp.monthOfSalary = i.toLong()
    }
}

 

결과값은 μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€. 😎