考虑以下字符串构建器的Kotlin实现:
class StringBuilder {
private val items = mutableListOf<String>()
fun append(item: String): StringBuilder {
items.add(item)
return this
}
override fun toString(): String {
return items.joinToString("")
}
}
StringBuilder
的内部实现需要一个可变的项列表,但是如果您想认真对待不可变性,可以很容易地将其重构为完全不可变的;例如:
class StringBuilder(private val items: List<String> = emptyList()) {
fun append(item: String): StringBuilder {
return StringBuilder(items + item)
}
override fun toString(): String {
return items.joinToString("")
}
}
根据Wikipedia,列于缺点下
生成器类必须是可变的。
但事实显然并非如此正如所展示的,构造器可以被设计成完全不可变的,并且事实上,这一陈述被列在"缺点"之下,这将暗示构造器不可变是有利的。
所以,我想知道是否有什么特定的原因,为什么构建器实现***应该是可变的?
- 我只能想到一个原因--不可变构建器的垃圾收集开销会更高,因为每次都必须返回构建器的新示例。*
2条答案
按热度按时间rjee0c151#
Builder模式的缺点包括:(3)
在Wiki中引用的那个要点的演示文稿并没有说“构建器类必须是可变的”或将其列为缺点,所以我发现该引用的位置是误导性的。
我认为你关于垃圾收集开销的观点是Kotlin?这样的语言的唯一缺点(除了在复杂的构建器中确保深度复制字段的不便之外)
w6mmgewl2#
你的不可变的例子是一个构建器在纯函数语言中实现的方式,正如你所说的,问题是所有额外的分配和相关的CPU周期。