如何在Kotlin中实现支持可重复步骤的分步构建器
Kotlin分步构建器实现支持重复步骤的Header-Item映射构建
完全可以通过Kotlin的阶段式分步构建器实现你的需求,核心思路是利用Kotlin的类型系统,通过不同的阶段接口约束每个步骤的可用操作,在编译期就强制符合你要求的步骤顺序,避免无效操作。
实现代码
1. 定义基础数据类
先定义Header和Item的核心数据结构:
data class Header(val name: String) data class Item(val content: String)
2. 划分构建阶段接口
通过三个接口明确不同阶段的可用操作,从类型层面限制步骤顺序:
// 初始阶段:仅允许添加Header interface InitialBuilderStage { fun addHeader(header: Header): ItemRequiredBuilderStage } // 待添加Item阶段:仅允许为当前Header添加Item,完成后进入可扩展/构建阶段 interface ItemRequiredBuilderStage { fun addItem(item: Item): BuilderStage fun addItems(vararg items: Item): BuilderStage } // 可操作阶段:允许添加新Header,或执行build生成最终结果 interface BuilderStage { fun addHeader(header: Header): ItemRequiredBuilderStage fun build(): Map<Header, List<Item>> }
3. 实现构建器核心逻辑
实现上述接口,内部维护构建状态,确保步骤合法性:
class HeaderItemBuilder private constructor() : InitialBuilderStage, ItemRequiredBuilderStage, BuilderStage { private val itemsPerHeader = mutableMapOf<Header, MutableList<Item>>() private var currentPendingHeader: Header? = null companion object { // 构建入口,返回初始阶段实例 fun start(): InitialBuilderStage = HeaderItemBuilder() } override fun addHeader(header: Header): ItemRequiredBuilderStage { check(currentPendingHeader == null) { "必须先为上一个Header添加至少一个Item" } currentPendingHeader = header itemsPerHeader[header] = mutableListOf() return this } override fun addItem(item: Item): BuilderStage { val header = currentPendingHeader ?: error("必须先添加Header才能添加Item") itemsPerHeader[header]?.add(item) currentPendingHeader = null // 标记当前Header已完成 return this } override fun addItems(vararg items: Item): BuilderStage { val header = currentPendingHeader ?: error("必须先添加Header才能添加Item") itemsPerHeader[header]?.addAll(items) currentPendingHeader = null return this } override fun build(): Map<Header, List<Item>> { check(currentPendingHeader == null) { "最后一个Header必须添加至少一个Item" } check(itemsPerHeader.isNotEmpty()) { "至少需要添加一个Header及其对应的Item" } // 返回不可变Map,避免外部修改内部状态 return itemsPerHeader.mapValues { it.value.toList() }.toMap() } }
有效示例
示例1:单个带Item的Header构建
val singleHeaderMap = HeaderItemBuilder.start() .addHeader(Header("用户基本信息")) .addItem(Item("姓名:张三")) .build()
示例2:多个带Item的Header构建
val multiHeaderMap = HeaderItemBuilder.start() .addHeader(Header("用户基本信息")) .addItems(Item("姓名:张三"), Item("年龄:25")) .addHeader(Header("订单信息")) .addItem(Item("订单号:20240501001")) .addItem(Item("支付金额:99元")) .build()
无效示例(编译期报错)
1. 无Header直接添加Item
// 编译错误:Unresolved reference: addItem val invalidMap1 = HeaderItemBuilder.start() .addItem(Item("无Header的Item")) .build()
原因:初始阶段InitialBuilderStage未暴露addItem方法,必须先调用addHeader进入下一阶段才能添加Item。
2. 仅添加Header未加Item就build
// 编译错误:Unresolved reference: build val invalidMap2 = HeaderItemBuilder.start() .addHeader(Header("空Header")) .build()
原因:添加Header后处于ItemRequiredBuilderStage,该阶段未暴露build方法,必须先添加至少一个Item进入BuilderStage才能执行构建。
内容的提问来源于stack exchange,提问作者Hector
相关产品推荐
相关产品推荐

