Пользователь библиотеки, обеспечивающий реализацию мультитонов через лямбду - PullRequest
0 голосов
/ 02 марта 2020

Исходя из Java Фон, я изучил этот , и он реализует мультитоны, но у меня другой случай, это пользователь моей библиотеки, который передает реализации во время выполнения.

Здесь есть два фрагмента кода: один принадлежит библиотеке (предварительно скомпилирован), а другой является пользователем кода библиотеки. Я могу изменить как библиотеку, так и код пользователя для достижения цели sh.

1. Код библиотеки (предварительно скомпилированный)

interface IPrinter {
    fun print()
}

open class Printer: IPrinter {

    companion object {
        private var printers = mutableMapOf<String, IPrinter>()

        @Synchronized
        fun getInstance(key: String, lambda: (key: String) -> IPrinter): IPrinter {
            if (printers[key] == null) {
                printers[key] = lambda(key)
            }
            return printers[key]!!
        }
    }

    private constructor(key: String) { // can use init too here.
        // some initializers
    }

    override fun print() {
        print("default implementation")
    }

    // ... other methods
}

2. Пользователь кода библиотеки , связанный с файлом jar

// it has to extend PrinterHost to inherit methods, problem -> Printer()
class PrinterImplementation: Printer(), IPrinter {

    companion object {
        fun getInstance(key: String): IPrinter {
            return Printer.getInstance(key) { key -> PrinterImplementation() }
        }
    }

    override fun print() {
        println("Print page from printer")
    }

}

// Usage: PrinterImplementation.getInstance("myPrinter")

Я думаю, что проблема с (2 пользователя кода библиотеки) состоит в том, что я создаю экземпляр Printer () из базового класса, пытаясь оберните голову вокруг этой реализации, где задействовано наследование.

1 Ответ

0 голосов
/ 02 марта 2020

Если вам всегда нужно key для построения Printer, это может выглядеть как

open class Printer protected constructor(key: String) : IPrinter {

    companion object {
        private var printers = mutableMapOf<String, IPrinter>()

        @Synchronized
        fun getInstance(key: String, lambda: (key: String) -> IPrinter): IPrinter {
            if (printers[key] == null) {
                printers[key] = lambda(key)
            }
            return printers[key]!!
        }
    }

    init { 
        // some initializers
    }

    override fun print() {
        print("default implementation")
    }

    // ... other methods
}

class PrinterImplementation(key: String): Printer(key), IPrinter {

    companion object {
        fun getInstance(key: String): IPrinter {
            // can also be written shorter: Printer.getInstance(key, ::PrinterImplementation)
            return Printer.getInstance(key) { key -> PrinterImplementation(key) }
        }
    }

    override fun print() {
        println("Print page from printer")
    }

}

Также рассмотрите возможность использования ConcurrentMap вместо MutableMap с @Synchronized:

    companion object {
        private val printers = ConcurrentHashMap<String, IPrinter>()

        inline fun getInstance(key: String, lambda: (key: String) -> IPrinter): IPrinter =
            printers.getOrPut(key) { lambda(key) }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...