Listener Idiom

I wonder if there is a preferred idiom on event listeners in Kotlin. My initial thought was: listeners with more than one method are pointless in Kotlin since lambdas cannot be used with them. As a result, i’d create all my listener interfaces like this:

interface FooListener {
    /**
     * Called when the foo event occurs.
     */
    public fun onFoo()
}

But Kotlin has these nice function types that render seperate interface declarations extremely verbose (especially when there are 5 interfaces because each interface is a SAM, e.g. MouseListener). In consequence, the listeners can be declared as functions:

class X {
    private val MutableList<() -> Unit> fooListeners = mutableListOf()

    public fun onFoo(listener: () -> Unit) = fooListeners.add(listener);

    public fun foo() {
        /* code ... */
        fooListeners.forEach{ it() }
    }
}

That version does not allow a doc-comment on the listener method. But that can be really important, especially when having to point out under what conditions a listener is invoked, to explain parameter ranges etc…

My questions are:

  • Ist there any idiom for this in Kotlin? How are true-Kotlin events+listeners to be implemented?
  • Can a function type be aliased (for the purpose of the doc comment)? And would that be any better than declaring an interface per event?

I think that using a list of elements of a function type is the most idiomatic solution for 1.0. Kotlin 1.1 will support type aliases, so you’ll be able to use them for the listeners.

2 Likes