用密封类定义有限业务结果类型(如success、failure),结合monad链式操作实现类型安全的业务流程;配合java 17+ switch模式匹配,强制处理所有分支,消除漏判风险。

用密封类(Sealed Class)配合函数式编程思想构建业务层的 Monad 模型,核心在于:用类型系统约束“所有可能状态”,再用 Monad 的链式结构封装上下文(如成功/失败、异步、空值),让编译器帮你守住安全边界。
用密封类定义有限、可穷举的业务结果类型
避免用 String 或 enum 表示操作结果,改用密封接口或类明确限定所有合法分支:
- 定义一个
sealed interface Result<t></t>,只允许Success<t></t>、Failure<e></e>、ValidationError<list>></list>等具体子类实现 - 每个子类都是
record,天然不可变、可比较、无副作用 - 新增一种业务结果(比如
RateLimited)时,必须显式添加新子类——编译器立刻报错提醒你更新所有switch或map处理逻辑
基于密封结果类型实现自定义 Either Monad
把 Result<t></t> 当作业务专用的 Either<e t></e> 容器,提供纯函数式操作原语:
通过聊天(Telegram / 飞书)执行本地 `clawusage` 监控命令。当用户输入 `/clawusage ...`,或提出“查看 Codex 用量”、“开启/关闭自动…”等请求时触发使用。
-
map(Function<t r>)</t>:仅在Success时转换值,Failure直接透传 -
flatMap(Function<t result>>)</t>:支持链式调用,自动扁平化嵌套Result<result>></result> -
recover(Function<throwable result>>)</throwable>:统一捕获异常并转为业务语义化的Failure
这样,库存校验 → 折扣计算 → 支付发起 就能写成一行可读、可测、不可跳过的管道:
orderResult.flatMap(this::checkInventory).flatMap(this::applyDiscount).flatMap(this::processPayment)与模式匹配深度协同,消除漏处理风险
Java 17+ 的 switch 表达式 + 密封类,让“处理所有分支”成为编译期强制要求:
- 写
switch (result) { case Success s -> ...; case Failure f -> ...; },若漏掉ValidationError,编译直接失败 - 结合 record 解构,直接提取字段:
case Success(Order order) -> sendConfirmation(order) - 在日志、监控、降级等横切逻辑中,也能安全地做类型分发,不依赖字符串判断
延伸:把状态流转也纳入密封+Monad体系
订单状态(Draft→Confirmed→Shipped→Delivered)本身就可以是密封类;再配合 State<orderstate order></orderstate> Monad,就能用纯函数描述状态迁移规则:
- 每个状态变更操作返回
Result<orderstate></orderstate>,天然携带错误上下文 - 用
flatMap组合多个原子操作,失败时自动中断流程并保留完整错误链 - 状态机不再靠
if-else或状态码硬编码,而是由类型系统和编译器共同守护










