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

移除函数副作用后,charge()方法应在何处调用?

关于移除函数副作用后charge()的执行位置与Mock使用问题

这个改造的核心是将业务决策逻辑与副作用执行分离:buyDonut只负责完成"购买甜甜圈"的业务规则(生成甜甜圈、记录支付信息),而实际的扣款操作(charge())被剥离到专门的副作用处理环节。

一、charge()方法的执行位置

你需要把charge()的调用放在程序的边界层——也就是专门和外部系统(比如支付网关、实际支付服务)交互的模块中。比如可以创建一个专门的支付处理器类,负责接收Purchase对象并执行实际扣款:

class PaymentProcessor {
    // 处理支付的副作用逻辑
    fun processPurchase(purchase: Purchase) {
        val payment = purchase.payment
        payment.creditCard.charge(payment.amount)
    }
}

在实际业务流程中,调用顺序会变成:

  1. 调用buyDonut(creditCard)得到Purchase对象
  2. 将Purchase传入PaymentProcessor.processPurchase()执行实际扣款

这样做的好处是,业务逻辑(买甜甜圈)和外部依赖(支付操作)完全解耦,buyDonut可以专注于业务规则,不用关心支付如何实现。

二、Mock的使用场景

  • buyDonut无需再用Mock:因为它已经变成纯函数,没有外部依赖,只根据输入生成固定输出,测试时直接断言返回的Purchase对象是否符合预期即可。
  • 边界层代码仍可能需要Mock:比如测试PaymentProcessor时,为了避免真实扣款,你需要MockCreditCard的charge()方法,或者用测试替身模拟支付网关的响应,确保支付逻辑的正确性(比如金额是否正确、是否调用了扣款方法等)。

这种分离方式让大部分业务逻辑变得易测、易维护,而副作用逻辑被集中管理,便于统一处理异常、重试、日志监控等场景。

内容的提问来源于stack exchange,提问作者Mohammadreza Khahani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 23:32:39