You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:40:17