我有一个场景,在这个场景中我需要将一个对象编组到XML中.该对象可以是多种类型,所以我创建了一个接口,将该对象类型设置为泛型T.

interface FileMarshaller<T> {
    fun marshal(object: T): File
}

并且我将有该接口的几个实现,每种类型的对象一个.这是其中之一:

internal class DocumentFileMarshaller : FileMarshaller<Document> {

    override fun marshal(document: Document): File {
        //some kotlin code
    }
}

很好,这就是我需要的.问题出在工厂.该工厂接收一个参数,并根据该参数决定应该检索哪个封送处理程序.

class FileMarshallerFactory {

    internal fun createMarshaller(fileType: FileTypes): FileMarshaller<What should I put here?> {
        when (fileType) {
            FileTypes.DOCUMENT -> {
                return DocumentFileMarshaller()
            }
            else -> throw MarshallerNotFound(MARSHALLER_NOT_FOUND)
        }
    }
}

问题出在工厂的返回类型上.我不能把它留空,我不能把文档作为它的类型,因为我会有更多的实现.如何处理此类型参数?也许除了我创建的这个工厂之外,还有其他方法?

推荐答案

在您的例子中,FileTypes确定什么是结果类型,并且它总是与特定类型相关,因此将其参数化也是有意义的.然后,它被用作T的"来源":

class FileMarshallerFactory {

    @Suppress("UNCHECKED_CAST")
    internal fun <T> createMarshaller(fileType: FileTypes<T>): FileMarshaller<T> {
        when (fileType) {
            FileTypes.DOCUMENT -> {
                return DocumentFileMarshaller() as FileMarshaller<T>
            }
            else -> throw MarshallerNotFound(MARSHALLER_NOT_FOUND)
        }
    }
}

sealed interface FileTypes<T> {
    object DOCUMENT : FileTypes<Document>
}

注意:您不能在这种方法中使用枚举.您需要一个密封的接口/类.

另外,老实说,这种代码设计对我来说有点陌生.如果有有限数量的封送处理程序,并且调用方需要知道它到底获取了哪个封送处理程序,它必须知道DocumentFileTypes.DOCUMENT,那么 for each 封送处理程序分别设置工厂不是更容易吗?通过多个函数或完全独立的类.也许这是因为我们看到的不是整个画面,而是一个简化的例子.

Kotlin相关问答推荐

在Kotlin Jetpack中重用下拉菜单

只能在元素区域中点击的Jetpack Compose列

如何在Kotlin中为接受varargs的函数添加带有默认值的新参数?

我可以更改方法中泛型类的类型参数边界吗?

如何在 micronaut 上启用 swagger UI?

Kotlin:伴随对象内的函数扩展

如何连接两个 kotlin 流?

is return inside function definition 也是 kotlin 中的表达式

从列表中的每个对象中 Select 属性

如何在 Kotlin 文件中的 Android Studio 中控制何时将 Imports 替换为通配符

变量后的Android问号

片段内的 Kotlin 按钮 onClickListener 事件

Kotlin 具体化的泛型不会按计划保持类型

Android Studio 和 Kotlin:Unresolved reference: also

Kotlin JVM 和 Kotlin Native 有什么区别?

Kotlin val difference getter override vs assignment

我应该使用Kotlin数据类作为JPA实体吗?

使用 kotlin 每 3 位数添加逗号或点

Kotlin:在何时使用枚举

Kotlin:如何使用扩展函数扩展枚举类