【发布时间】:2021-07-06 17:55:57
【问题描述】:
目标是将通用对象(不同类型参数)的列表存储在列表中,并以类型安全且符合人体工程学的方式对其进行操作。
我当前的设计使用访问者模式:
sealed interface Element {
fun visit(visitor: Visitor)
}
interface Visitor {
fun <T> accept(elementA: ElementA<T>)
}
data class ElementA<T>(
// example members, many more in the real code
val produce : () -> T,
val doSomething: (T) -> Unit
) : Element {
override fun visit(visitor: Visitor) = visitor.accept(this)
}
尽管如此,访问者写起来不是很方便,因为必须继承Visitor:
fun exampleUse(elements: List<Element>) {
for (element in elements) {
element.visit(object : Visitor {
override fun <T> accept(elementA: ElementA<T>) {
// We don't care about the actual type T, just that it exists
elementA.doSomething(elementA.produce())
}
})
}
}
这不是很符合人体工程学,我希望用户只需要编写常规和短代码,例如
element.visit {it.doSomething(it.produce())}.
唯一的要求是:
- 元素应该可以存储在一个列表中(同构集合)
- 用法(例如:
a.doSomething(a.produce()))应与类分开,因为它们是在具有不同关注点的不同包中定义的。
如果有办法避免访问者样板,那就更好了。
【问题讨论】: