写点什么

声明式编程:by example

作者:agnostic
  • 2023-04-02
    上海
  • 本文字数:1154 字

    阅读完需:约 4 分钟

声明式优于命令式编程,这个是晚上大量文章中建议的观点。同时比较喜欢举的例子就是 SQL 语言。但是,我们在日常的架构设计过程中,怎么实现算声明式设计,声明式能收到什么样的好处,估计大部分的架构师还是有一定困惑的。最近在做外汇服务和链路的升级,中间有个例子可以很好的说明问题。


业务场景很简单:就是在做外汇交易时,首先需要获取报价信息。虽然获取报价是一个很简单的交互,本质就是要拿到一个价格。但是,由于外汇业务的特殊性,给到客户的价格,和客户、业务场景、时间段等有密切的关联,同时还有营销优惠券需要考虑。


最初的设计,是妥妥的一个命令式编程的范例。获取报价的系统会顺序执行如下步骤:

  1. 根据用户 Id,去行业外汇系统咨询得到用户相应的等级信息;

  2. 根据支付场景(户到户还是流出、结汇还是非结汇等),根据参数中心的配置获取外汇场景码;

  3. 获取用户在页面上选择的营销券;

  4. 结合上面的信息,再带上交易币种金额,去外汇中台获取报价;

  5. 计算出最终的交易对手方金额。

这个设计在日常运营过程中,遇到过相当多的问题:

  • 新增站点缺少支付场景和外汇场景码的配置,导致获取报价失败;

  • 每次一个场景的改动,都需要回归所有场景,否则就容易导致报价逻辑错误;

  • 每次外汇报价策略的改动,都需要所有询价相关调用方进行改造和回归;

  • 最后一步计算,经常由于 offer 和 bid 价格用错导致金额有偏差。

纠其根本原因,就是这个命令式的交互设计,违反了高内聚低耦合的原则,将外汇相关的领域知识扩散到了上游的使用方,导致运营、变更都有很大的开销。


对于这个问题,如果我们引入声明式的设计,就可以很好的解决这个问题。

上游不需要理解各个步骤,只需要了解自己的诉求:针对单个用户、单个交易场景,顺带带上优惠券信息,加上交易自带的金额和币种,获取一个合适的价格。

所以,报价的接口设计就成为了这么一个函数:

报价服务提供方会完成上述的过程的执行:

  1. 根据 userId 获取用户等级;

  2. 根据 bieScene 获取外汇报价策略;

  3. 将 benefitId 翻译成点差或者券信息;

  4. 调用中台获取价格;

  5. 计算 buyAmount 返回上游。

同时,未来如果有一些变更的需求,上游也完全不需要感知:

  • 用户等级升级成 by 单用户运营的价格优惠,或者根据用户历史交易量打的分数;

  • 增加按照时间段的报价策略,应对周末无市场的场景;

  • 根据交易金额分级定价;

  • ……


总结一下,对于声明式样的设计,屏蔽内部的实现逻辑,暴露给上游明确的业务信息输入,处理后返回明确的执行结果。声明式的设计,就是很好的将架构职责做了一个明确的切分:调用方只需要了解自己业务领域边界内部的概念,将业务要素给到服务提供方后,有提供方执行并返回同样有业务含义的结果信息。由于架构职责的清晰切分,从而满足了高内聚低耦合的特性,最终在集成、变更和运营运维上都可以收到理想的效果。


发布于: 刚刚阅读数: 3
用户头像

agnostic

关注

常识、KISS、高可用、合规架构、架构治理 2019-02-14 加入

二十年架构经验,互联网金融专业架构师。Open Group Master Certified Architect

评论

发布
暂无评论
声明式编程:by example_声明式_agnostic_InfoQ写作社区