DCI in Kotlin

6 views
Skip to first unread message

Matthew Browne

unread,
Feb 18, 2026, 7:12:11 AM (5 days ago) Feb 18
to object-co...@googlegroups.com

I spent some time implementing DCI in Kotlin, and it turns out it's quite a nice language for it. Here's a simple money transfer example, using the technique I learned from this article that I shared in an earlier thread:

class Account(private var _balance: Int): MoneySource, MoneyDestination  {
    override val balance: Int
        get() = _balance

    override fun increaseBalance(amount: Int) {
        _balance += amount
    }

    override fun decreaseBalance(amount: Int) {
        _balance -= amount
    }
}

interface MoneySource {
    fun decreaseBalance(amount: Int): Unit
    val balance: Int
}

interface MoneyDestination {
    fun increaseBalance(amount: Int): Unit
    val balance: Int
}

fun TransferMoney(
    source: MoneySource,
    destination: MoneyDestination,
    amount: Int
) {
    class DestinationAccountRole {
        fun MoneyDestination.deposit() {
            increaseBalance(amount)
        }
    }

    class SourceAccountRole {
        fun MoneySource.transferToDestination() {
            require (balance >= destination.balance, {"Insufficient funds"})
            withdraw()
            with (DestinationAccountRole()) {
                destination.deposit()
            }
        }

        private fun MoneySource.withdraw() {
            decreaseBalance(amount)
        }
    }

    with (SourceAccountRole()) {
        source.transferToDestination()
    }
}


There's also a simpler way to do it, without the with statements:
https://github.com/mbrowne/dci-examples/blob/main/kotlin/src/moneyTransferAltVersion/moneyTransfer.kt

But I like the version with with (even though it's a bit tedious) because it allows you to group the role methods in role classes, and the name of the role appears in the code when you're calling role methods.

And here's the Dijkstra example:
https://github.com/mbrowne/dci-examples/tree/main/kotlin/src/dijkstra

For that one I had to introduce a context class even though I didn't need a long-lived context, because there's a limitation when putting classes inside of functions in Kotlin: it only works if there are no circular dependencies between roles. (Disclaimer: after writing the initial version, I asked Gemini for some help on the Dijkstra example, to make it more idiomatic Kotlin.)

My conclusion is that Kotlin is a promising language for DCI. Another reason I'm excited about DCI in Kotlin is that it has so many compiler targets now: in addition to the JVM / Android, it compiles to native code (meaning it can also be used for iOS—and its UI framework can target iOS too), WebAssembly, or JavaScript. They re-architected the compiler a few years ago, and if anyone wanted to introduce dedicated syntax for DCI (role / context) and proper role-object contracts, that would be entirely doable.

What do you all think?
—Matt

Reply all
Reply to author
Forward
0 new messages