【发布时间】:2018-10-01 10:23:31
【问题描述】:
我有一个配置元素的层次结构,它们都实现了一个接口(简化):
interface Configuration {
val elements: Long
val data: Long?
var parent: Configuration?
}
jackson-kotlin 将通过读取 Yaml 文件来构建实现,如下所示:
checks:
elements: 10
data: 1234
ports:
elements: 5
代码也可以这样做:
CheckConfig(elements = 10, data = 1234, portConfig = PortConfig(elements = 5))
我的问题是 - 当我构造 PortConfig 时,我还不知道它的父级。 Jackson 可能,但我不知道如何利用这一点。
如果用户没有为此特定配置部分提供任何data 属性,PortConfig 实现需要其父级回退。
我现在做的事情感觉很老套:
inline fun <reified T: Configuration> T.updateChildLinks() {
(this::class as KClass<T>).memberProperties.forEach {
if (it.returnType.isSubtypeOf(Configuration::class.createType(nullable = true))) {
it.isAccessible = true
val config: Configuration = it.get(this) as Configuration
config.parent = this
}
}
}
并在每个父母的init 块中调用它。我可以做得更好吗(特别是我不喜欢我必须记住在 init 阶段调用辅助函数)?
编辑添加:以前,我有一个纯代码解决方案,可以将data 传递到链中:
CheckConfig(elements = 10, data = 1234,
portConfig = PortConfig(elements = 5, parentData = 1234))
然后让data 旁观parentData,但我在与杰克逊一起工作时遇到了麻烦。
【问题讨论】:
-
为什么
CheckConfig不能适当地设置portConfig.parent?如果您害怕忘记设置它,您也可以创建一个界面,例如PreConfiguration包含与Configuration相同的内容,但parent除外。然后将PreConfiguration作为参数给出,并且必须通过方法(采用parent)将其转换为Configuration,然后才能使用。 -
是的,这基本上就是我的 hack 所做的。但是由于层次结构是用 jackson 构建的(并且只有测试显式地构建类),我想我可以利用它。