Я пытаюсь создать класс Synchronization, в который могут регистрироваться внешние модули, но я не могу заставить работать стандартную часть.
Внешние модули зарегистрируют SynchronizationBundle<SynchronizableType>
на Synchronizator
, который должен затем обрабатывать синхронизацию.
interface Synchronizable<T : Synchronizable<T>>
object SynchronizationBundles {
val bundles: MutableMap<KClass<*>, SynchronizableBundle<*>> = mutableMapOf()
fun <T : Synchronizable<T>> register(kClass: KClass<T>, bundle: SynchronizableBundle<T>) {
bundles[kClass] = bundle
}
@Suppress("UNCHECKED_CAST")
operator fun <T: Synchronizable<T>> get(kClass: KClass<T>) : SynchronizableBundle<T> {
return bundles[kClass] as? SynchronizableBundle<T> ?: throw IllegalArgumentException("No bundle for ${kClass.simpleName}")
}
}
Например, при операции синхронизация ондолжен перебирать зарегистрированные пакеты и уметь работать с конкретными реализациями Synchronizable<T>
.Впереди псевдокод
fun synchronize() {
bundles.forEach { bundleEntry ->
val bundle = bundles[bundleEntry.key]
val synchronizables = bundle.api.get()
remoteSynchronizables.forEach { remoteSynchronizable ->
val localSynchronizable = bundle.datastore.getByPlatformId(remoteSynchronizable.platformId)
val synchronizableToInsert = bundle.conflictStrategy.resolve(localSynchronizable, remoteSynchronizable)
synchronizableToInsert?.let {
bundle.datastore.insert(it.withUploadStatus(UploadStatus.COMPLETED))
}
}
}
}
Проблема в том, что val bundle = bundles[bundleEntry.key]
возвращает SynchronizableBundle<*>
, поэтому я не могу вызвать .conflictStrategy.resolve
, поскольку он ожидает Synchronizable<T>
В качестве примераэто определение ConflictStrategy
.Api и Datastore следуют одному и тому же шаблону
interface ConflictStrategy<T : Synchronizable<T>>
Возможно ли это вообще?Я уверен, что я не первый, кто попробует этот подход.
Если бы я мог как-то вызвать val bundle = bundles[MySynchronizable::class]
, я бы получил SynchronizableBundle<MySynchronizable>
, но мне не удалось это сделать.Кроме того, типы Synchronizator
будут работать с внешними модулями, поэтому я даже не знаю, сработает ли конкретный KClass
.
Работа с функциями более высокого порядка, возможно, облегчит мою жизньи этот Синхронизатор может быть независимым от типа, но я не пробовал.
Спасибо!