Kotlin

[코틀린 코딩 습작] Double Dispatch

[하마] 이승현 (wowlsh93@gmail.com) 2021. 5. 15. 19:05


interface Account {

}

class EthreumAccount(val gas: Int) : Account{

}

class FabricAccount(val org: String) : Account {

}

class BlockChain(val networks : Map<String,String>) {

    fun send(account: Account) {
        when(account) {
            is EthreumAccount -> {
                val gas = account.gas
                val network = networks.get("eth")
                println("send to ${network} with gas: ${gas}")
            }
            is FabricAccount -> {
                val org = account.org
                val network = networks.get("fab")
                println("send to ${network} with org: ${org}")

            }
            else -> {
                println("illegal parameter exception!!")
            }
        }
    }
}

fun main() {
    println ("================= start ================")
    val blockchain = BlockChain(mapOf(Pair("eth","address-1"),Pair("fab","address-2")))
    val account1 = EthreumAccount(3)
    blockchain.send(account1)
    val account2 = FabricAccount("navy")
    blockchain.send(account2)

}

- BlockChain 클래스에 너무 많은 책임이 몰려있다. 
- if문으로 새로운 account타입이 들어올 때마다 분기해줘야 한다. 

더블디스패치방식으로 리팩토링 해보자.

import jdk.nashorn.internal.ir.Block


interface Account {
    fun send(blockchain: BlockChain)
}

class EthreumAccount(val gas: Int) : Account{

    override fun send(blockchain: BlockChain){
        val network = blockchain.networks.get("eth")
        println("send to ${network} with gas: ${gas}")
    }
}

class FabricAccount(val org: String) : Account {

    override fun send(blockchain: BlockChain){
        val network = blockchain.networks.get("fab")
        println("send to ${network} with org: ${org}")
    }
}

class BlockChain(val networks : Map<String,String>) {

    fun send(account: Account) {
       account.send(this)
    }
}

fun main() {
    println ("================= start ================")
    val blockchain = BlockChain(mapOf(Pair("eth","address-1"),Pair("fab","address-2")))
    val account1 = EthreumAccount(3)
    blockchain.send(account1)
    val account2 = FabricAccount("navy")
    blockchain.send(account2)

}