How do you resolve circular imports in Kotlin

Kacper Floriański

I'm new to programming in Kotlin and I've already managed to run into the classic circular dependency issue - I know Kotlin can cope with those but I'd like to know how would I go about changing my design to avoid it. What structures or Kotlin functionality should I use in the following?

import MyClass

interface MyInterface {
    fun useMyClass(myInstance: MyClass)
}
import MyInterface

class MyClass(myList: List<MyInterface>) {
    val storedList: List<MyInterface> = myList
    var myValue: Int = 10
}

I would like MyClass to store multiple objects which implement MyInterface, but I would also like each of those objects to reference the class they have been passed to, i.e. each call of useMyClass would have the signature of useMyClass(this).

For example, I could create a class

class ImplementingMyInterfaceClass(): MyInterface {
    override fun useMyClass(myInstance: MyClass) {
         myInstance.myValue += 10
    }
}

and call it somewhere within MyClass:

ImplementingMyInterfaceClass().useMyClass(this)

Technically I could create another construct in the middle which would be used by MyInterface and inherited/implemented by MyClass, but this just doesn't feel correct. Any suggestions?

Note: In my specific issue, it might be helpful to consider each implementation of MyInterface as a sort of a "modifier" (since it will modify the instance of the class) - MyClass instances should be aware of its modifiers and each modifier should be able to modify that instance.

Tenfour04

It's going to largely depend on what the interface has to do, but you could limit its function argument to some interface that MyClass implements:

interface MyInterface {
    fun increaseSomeValue(someValueHolder: MySubInterface)

    interface MySubInterface {
        var myValue: Int
    }
}

class MyClass(myList: List<MyInterface>): MyInterface.MySubInterface {
    val storedList: List<myInterface> = myList
    override var myValue: Int = 10
}

Or your interface can take a property argument:

interface MyInterface {
    fun increaseSomeValue(someValue: KMutableProperty<Int>)
}

class MyInterfaceImpl: MyInterface {
    override fun increaseSomeValue(someValue: KMutableProperty<Int>) {
        someValue.setter.call(someValue.getter.call() + 10)
    }
}

// from MyClass:
storedList.first().printSomeValue(::myValue)

In other cases where we don't need to both get and set, it could be cleaner to take a more versatile function argument (lambdas could be passed):

interface MyInterface {
    fun printSomeValue(valueProvider: () -> Int)
}

class MyInterfaceImpl: MyInterface {
    override fun printSomeValue(valueProvider: () -> Int) {
        println(valueProvider())
    }
}

// from MyClass:
storedList.first().printSomeValue(::myValue)
// or
storedList.first().printSomeValue { 1..10.random() }

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to resolve circular dependency in Gradle

How to avoid circular imports in Python?

How to avoid circular imports in Python?

How do you structure imports for testing inside a module of your project?

How do you "resolve" a GKTurnBasedExchange?

How do you rotate (circular shift) of a Scala collection

How does Angular2 resolve imports?

How do you resolve 'hidden imports not found!' warnings in pyinstaller for scipy?

How to resolve circular dependency in DbContext

How do you annotate Pair parameter in Kotlin?

How do I resolve this diamond problem in Kotlin?

Kotlin Multiplatform Android Imports won't resolve

How do I resolve this Angular 7 "Circular dependency detected" warning

How do you use ManyToManyFields between apps without producing circular imports?

How to avoid circular imports?

How do you crop an image to be circular with pillow in discord.py?

How to resolve this circular dependency in EF

How do you use parent module imports in Rust?

How do you organize imports in Eclipse with Pydev?

How do you avoid circular imports in Python?

Circular dependency - how to resolve and avoid

How do you resolve an OCaml circular build error?

How to Do Nested Imports

How do you serialize a Parcelable to a String in Kotlin?

How do you make an <a> element circular?

How do you find the dependencies you need for some imports?

How do you fix this circular dependency issue in node

How do you serialize a list of BufferedImage in Kotlin?

How do I access a variable defined outside my class in a separate file without running into circular imports?