我目前正在编写一些代表符号数学表达式的类。所有这些都是不可改变的。
然而,我发现自己经常重复相同类型的结构,所以我创建了一个接口以避免重复,但发现自己无法避免重复“substituteInside”方法(见下文),该方法返回对象的副本对应于“find”的组件替换为“replace”。
此行为的所有实例的行为都相同。
在我目前的解决方案中,接口需要实现一个方法createOp
,它返回对象的修改后的副本。
interface UnarySymbolicOp<InType : Any,
OutType : Any,
OpType : UnarySymbolicOp<InType,OutType,OpType>> :
Symbolic<OutType> {
// Arg may be a complex expression
val arg: Symbolic<InType>
fun createOp(mesh: Symbolic<InType>) : OpType
override val variables
get() = arg.variables
override fun <V : Any> substituteInside(find: Symbolic<V>, replace: Symbolic<V>): OpType {
return createOp(arg.substitute(find, replace))
}
}
然后可以按如下方式实现接口:这些类表示获取表达式的某些组件的操作。
data class GetX(override val arg: Symbolic<Vector3d>) : UnarySymbolicOp<Vector3d, Double, GetX> {
override fun createOp(mesh: Symbolic<Vector3d>) = GetX(arg)
override fun eval() = arg.eval().x
}
data class GetY(override val arg: Symbolic<Vector3d>) : UnarySymbolicOp<Vector3d, Double, GetY> {
override fun createOp(mesh: Symbolic<Vector3d>) = GetY(arg)
override fun eval() = arg.eval().y
}
data class GetZ(override val arg: Symbolic<Vector3d>) : UnarySymbolicOp<Vector3d, Double, GetZ> {
override fun createOp(mesh: Symbolic<Vector3d>) = GetZ(arg)
override fun eval() = arg.eval().z
}
这改善了事情,因为返回对象副本的其他方法可以使用该方法,因此可以在接口中生存,但我仍然需要在任何地方复制此方法,而它基本上总是做同样的事情。