系统设计 / 访问控制 · 从 RBAC 查表到 policy 判定函数 / 会员价 + 优惠券:当 policy 不输出准/拒,而是算一个价 待审核 20 / 23
实例 · 会员价 / 优惠券

会员价 + 优惠券:当 policy 不输出准/拒,而是算一个价

收银台那行「应付 ¥XX」,本质和前五页的判定一模一样:把一套促销规则(rule)应用到购物车(context)上。唯一的推广是——这次决策不再是 permit / deny,而是一个值(最终价)加上用了哪些优惠。这就是规则引擎(rule engine),policy 的近亲。四个轴照样在。

图 0-1 · 定价场景里的四个轴各自对应什么。

注 · 一条优惠券就是一条 rule,和 组合算法 一页的规则同构,只是 effect 从 permit/deny 变成改价:条件 when(cart) 是「满 200 / 限图书 / 限新人」,效果 effect 是「−¥30 / ×0.95 / 包邮」,再加互斥组与优先级。而「会员价和券能不能叠?多张券怎么算?谁先谁后?」就是组合算法的促销版——而且它顺序敏感。

1 · 收银台促销引擎

引擎逐条走过规则:会员价先落,再按当前叠加策略处理折扣券与满减券,最后结算运费。跳过的券会给出跳过原因。

图 1-1 · 一辆购物车经促销规则求值得到实付价的全过程。可调数量、会员等级、持有券与叠加策略,观察每条优惠省了多少或为何跳过。

2 · 三种叠加策略下的实付价

叠加策略不是细节,它直接决定付多少——也决定商家让不让这么省。

图 2-1 · 当前购物车在三种叠加策略下的实付价对照,最省的一格带标记。

警示 · 顺序敏感直接影响金额。对比「先折扣后满减」与「先满减后折扣」:满减是固定减额,折扣是乘法——谁先谁后,最终价不同(本页满减门槛按原价判,所以差异全来自「−额」落在「×折扣」前还是后)。真实电商必须把应用顺序写死进文档,否则同一车在两次结算给出不同价,就是事故。这正是 first-applicable「顺序即优先级」的同一机制。

建议 ·「自动选最省」是在 policy 空间里做优化。券互斥策略下,引擎会把每张可用券各算一遍,挑实付最低的那一张,其余标「互斥跳过」。这比单纯判 permit/deny 更进一步:决策从「命中哪条」升级成「哪种组合最优」。也正因为叠加往往比互斥更省,商家才用互斥来控制让利成本。

3 · 促销概念映回 policy 概念

表 3-1 · 促销术语与前五页 policy 概念的逐条对应。
促销里的说法 policy 里的概念
满 200 / 限图书 / 限新人 规则条件 when(req)(eligibility / applicability)
−¥30 / ×0.95 / 包邮 规则效果 effect(不是 permit/deny,而是改价)
券与券 / 券与会员价互斥 combining algorithm:互斥约等于选一个(本页取最优)
先满减还是先打折 应用顺序,约等于 first-applicable「顺序即优先级」
折扣封顶 / 最低实付 ¥0 约束 / obligation(上限下限)
没有任何券命中 默认决策 = 原价(default,no-op 的 permit)
最终「应付」 decision 的返回值(一个数,不是布尔)

4 · 参考文献

  1. Wikipedia. Business rules engine. 促销/定价引擎所属的规则引擎家族,条目举的例子正是「满 100 减 10%」这类促销规则,并单列一节讲它在授权上的用法——policy 的近亲。en.wikipedia.org