Kotlin Делегирование, как получить доступ к свойствам класса из объекта делегата. - PullRequest
1 голос
/ 20 марта 2020

Я пытаюсь отделить некоторые работы от гигантского класса, чтобы обеспечить большую читабельность. Сначала я посмотрел на Extension, но, похоже, он просто создает некоторые функции stati c, затем мне в глаза попался шаблон делегата.

Приведенный ниже код выглядит хорошо, и делегат работает так, как если бы он был частью класса EnhancedProducer. Но есть одна проблема, которая блокирует меня, я не совсем понимаю, как получить доступ к свойству службы класса EnhancedProcuder из делегата. В моем реальном коде есть несколько случаев, когда исходный класс и класс делегата должны использовать переменную службы одновременно, поэтому я не знаю, есть ли способ сделать это.

Я понимаю, что мы, вероятно, можем внедрить экземпляр службы в оба из них, но я все еще хочу выяснить, существует ли более элегантный способ сделать делегат более естественно вписывающимся в класс EnhancedProducer.

interface Producer {

    fun produce()
}

class ProducerImpl : Producer {

    override fun produce() {
       // service.doSomething() how to access service here
       println( "ProducerImpl")
    } 
}

class EnhancedProducer(private val delegate: Producer) : Producer by delegate {

    // how to share this with delegate 
    //private val service = Service() 

    fun test() {
        produce()
    }
}

fun main() {
    val producer = EnhancedProducer(ProducerImpl())
    producer.test()
}

Ответы [ 2 ]

1 голос
/ 20 марта 2020

В конце концов я нашел решение, которое сразу после ключевого слова инициализирует ProducerImpl. Это так странно, что все примеры, которые я нашел до сих пор, только пытаются внедрить экземпляр, а не обеспечивают инициализацию, когда необходимо делегирование. Может, кто-нибудь что-нибудь знает об этом?

interface Producer {

    fun produce()
}

class ProducerImpl(val service:Service) : Producer {

    override fun produce() {
        service.doSomething()
        println(item)
    }
}

class EnhancedProducer(val service:Service) : Producer by ProducerImpl(service) {
    fun test() {
        produce()
    }
}

fun main() {
    val service = Service()
    val producer = EnhancedProducer(service)
}
0 голосов
/ 20 марта 2020

Может использовать открытые свойства в интерфейсе:

interface Producer {
    fun produce()
    // two classes will use/modify this property 
    var service: Service 
}
...
class ProducerImpl: Producer {
    override var service = Service()

    fun changeService() {
        service.execute() // access to the interface field
    } 
}
...
class EnhancedProducer(private val delegate: Producer): Producer by delegate {
    fun test() {
        this.service // access to the interface field
        delegate.service // access to the interface field
        produce()
    }
}

fun main() {
    val producerImpl = ProducerImpl()
    val producer = EnhancedProducer(producerImpl)
    producerImpl.service // access to the interface field
    producer.service // access to the interface field
}
...