kuanat
165 天前
这是个业务或者说工程问题,不全是技术问题。因为不像 Java 用 BigDecimal 比较多,Go 这边没有习惯性做法,所以主要靠约定,剩下的是如何执行。无论哪种语言,计算这类纯技术问题都是小事,与业务结合的部分才是大事。
我这里说几个技术人员可能不太熟悉的业务需求或者是需要注意的点:
- 最理想的是用 Go 自定义数据结构,在数据结构上实现相应的运算方法。这样可以避免代码上的出错。这里比较关键的点是,计算过程肯定是高精度/整型(对应 BigDecimal ),同时一定要支持 split 操作,主要是处理类似 1 拆成 0.33+0.33+0.34 的业务需求,这种在会计、税务场景很常见。
- 根据全流程数据交换的环节来定义精度和数据格式。一般推荐的是比常见货币最小单位更精确一点,或者支持自定义。传递过程中使用字符串,做好格式转换。说到底还是靠约定,为了方便执行可以独立成库强制所有上下游都使用特定实现。
- 有需要的话提前考虑多币种支持,比如订单系统如果可以支持多币种,数据库和业务逻辑都要做 schema 调整。通常的业务需求来说,多币种就是多账本,如果最初设计成单账本后期修改会很痛苦。
- 推荐使用 event driven 架构来做 cqrs ,即用事务的方式持久化变动,实时状态由历史计算推导得出。类似银行卡只记录进出,余额是算出来的。好处一方面能和通常的消息队列架构方便对接,另一方面整个业务的可靠性、灾难恢复都好做。有 olap 需求也容易改造。