策略的基本概念:规则、条件、动作与作用域

聊边界策略,绕不开四个基本元素:规则、条件、动作和作用域。

你可能觉得这些词儿很基础,确实。但在实际项目中,我发现很多人对它们的理解是模糊的。规则写错了位置,条件和动作混在一起,作用域没理清楚——最后导致边界验证失控。

这章我们就掰开揉碎讲清楚。理解透了,后面写策略才不会跑偏。

什么是规则?

规则,说白了就是一条“如果-那么”的逻辑句。它定义了:当某个条件满足时,应该执行什么操作。

我习惯把规则看作策略的最小单元。一个策略可能包含多条规则,每条规则独立、自洽。

规则的本质结构
规则 = 条件 + 动作

例如:如果(用户年龄 < 18)则(禁止访问)

好的规则,要满足三个特征:

  • 原子性:一条规则只做一件事。别把多个逻辑揉在一起。
  • 确定性:同样的输入,永远得到同样的输出。换句话说,规则必须是纯粹的。
  • 可验证性:写出来的规则,应该能逐条写出测试用例去验证。

我在项目中遇到过一条经典的“坏规则”:「如果用户是VIP且购买金额大于1000,或者注册时间超过一年,则打折。」这条规则里条件混在一起,边界非常模糊。你想想看,“VIP且金额大于1000”是一个组合条件,“注册时间超过一年”又是一个独立条件——它们的优先级怎么算?

什么是条件?

条件是规则中的判断部分。它决定了规则是否被触发。

条件可以很简单:价格 > 100。也可以很复杂:(价格 > 100 && 库存 > 0) || 会员等级 > 3。

我的个人习惯:把每个条件拆到最细。比如不要写 价格 > 100 && 库存 > 0,而是写成两条规则,或者用条件组合表明确。为什么?因为测试边界时,你得枚举每个条件的真/假组合——组合越多,测试量爆炸得越快。

条件的类型通常分三种:

类型 示例 边界策略要点
范围条件 温度 ∈ [0, 100] 闭区间 vs 开区间要明确,0.0 和 100.0 算不算边界?
枚举条件 状态 ∈ {待审核, 已通过, 已拒绝} 每个枚举值都算一个边界,还要考虑空值和非法值。
组合条件 A && B || C 短路逻辑、优先级、括号位置都会影响边界。

什么是动作?

动作是规则触发后执行的操作。它可能是返回一个值、调用一个函数、修改一个状态、或拒绝一个请求。

动作虽然看起来简单,但经常踩坑。为什么呢?因为动作之间可能有副作用。

  • 举个例子:规则A触发了「发送通知」,规则B触发了「更新积分」。但这两个动作有顺序要求吗?如果发送通知时积分还没更新,用户看到的数据就不对。
  • 再比如,动作「拒绝请求」之后,后面的规则还应该继续执行吗?在策略引擎中,这叫做短路控制。
我曾经犯过的错:在一个风控策略中,动作「记录日志」和「拦截交易」写在了同一条规则里。结果日志记录本身抛异常了,导致拦截动作没执行——交易放行了,后面出了大问题。现在我写动作时,一定会把飞功能性操作(日志、统计、通知)和核心业务动作拆开,分到不同的规则里。保证核心动作不受外围操作的影响。

什么是作用域?

作用域定义了规则在什么粒度下生效。这是最容易忽略、也最容易出问题的地方。

作用域通常有三个维度:

  1. 数据维度:规则针对的是单个实体(比如一条订单)、还是多个实体(比如所有订单)?
  2. 时间维度:规则是即刻生效,还是在某个时间段内有效?比如“双十一期间折扣规则”只在特定日期生效。
  3. 层级维度:规则属于全局策略,还是只对某个分组有效?比如“VIP客户单独的积分规则”。

举个例子。你在电商系统里写了一条规则:「如果订单金额 > 500,免运费。」

  • 作用域是单订单,没问题。
  • 但如果用户同时下了三个订单,每个金额都不到500,合计超过1500——免不免?这取决于你的作用域是“每个订单”还是“整单”。
边界策略中作用域的关键问题
  • 跨实体聚合时,规则是否还成立?
  • 规则执行过程中,作用域内的数据发生变化怎么办?
  • 多个规则的作用域重叠时,按什么顺序生效?

四个要素的关系

规则、条件、动作、作用域并不是孤立的。它们组合起来,才构成一个完整的策略。

我画了一张图来说明它们的关系。嗯,这里面比较重要的一点是:作用域是规则的“上下文容器”,条件和动作都在这个容器里运行。

策略四要素关系图 作用域(Scope) — 定义了规则的生效范围(数据、时间、层级) 规则(Rule) 条件(Condition) 动作(Action) 规则由条件 + 动作组成 并且运行在作用域定义的上下文中

一个完整的策略示例

说了这么多,不如来个完整的例子。假设你写一个简单的 支付风控策略:

策略:风控校验
作用域:单笔支付交易

规则1:
  条件:交易金额 > 5000 且 用户为新注册(注册天数 < 7)
  动作:拒绝交易

规则2:
  条件:交易金额 > 10000
  动作:触发人工审核

规则3:(默认规则)
  条件:以上规则均未触发
  动作:放行

这个策略里,

  • 作用域明确是“单笔支付交易”,不同笔交易互不影响。
  • 规则1和规则2的条件之间有重叠:金额大于10000且新注册的用户,同时满足两条规则。这时候顺序就重要了——规则1先执行的话,直接拒绝,规则2没有执行机会。这需要你明确规则之间的优先级。
  • 动作包括拒绝、人工审核、放行,互斥但清晰。
提示:实际的策略引擎中,规则之间可以有「命中即返回」、「全部执行再聚合」、「加权评分」等多种模式。写策略前,先搞清楚引擎的行为模型。

避坑指南

  • 条件别写得太聪明。我曾经看到有人写 amount & 0x01 做奇偶校验——看起来很酷,但后来没人能读懂这条规则是什么意思。条件应该是领域语言,不是代码炫技。
  • 动作必须可回滚。如果能回滚,策略就有自我修复能力。不能回滚的动作(比如发送已发邮件),要想好补偿机制。
  • 作用域没搞清楚之前,不要写规则。很多时候边界问题不是因为条件写错了,而是作用域设错了。比如你定义的是全局规则,但实际业务只对特定区域生效——线上自然会出问题。

好,基本概念就讲这么多。记住一句话:规则是骨架,条件是判断,动作是执行,作用域是上下文。四个东西对了,策略不会太差。