如何表达业务规则?用声明方式!


下面这个比喻可以说明声明性规范与过程性规范之间的区别:

  • 编写一个计算机程序。
  • 在单独的卡片上注明每条语句。
  • 将这卡片交给操作员执行。
  • 确保程序运行正常,没有错误。
  • 将卡片高高抛起。
  • 按随机顺序捡起地上的卡片(确保没有遗失任何一张,而且都是正面朝上)。
  • 将卡片交给操作员再次执行。
  • 检查结果。
  • 如果逻辑仍能正常执行,那么它就是声明式的。如果不能,那就是程序性的。

如此简单,但如此强大的测试!

这是以上测试过程的含义,也就是其中原理:

  • 如果程序仍能正常运行,那么逻辑中就没有隐藏的语义。将卡片(语句)提交给机器执行的顺序对结果没有任何影响。
  • 如果程序不能正常运行,那么即使读完整副卡片组,机器也无法访问所有语义。有些语义隐藏在单张卡片之间,即隐含在指令序列中。

题外话:不要把逻辑依赖误认为顺序依赖。例如,如果净利润的计算依赖于总收入的计算,那么显然必须先计算总收入,即使不是最先出现的语句。但是,机器也能像人一样,根据两条规则中共同的 "总收入 "一词推算出这一点。

在商业和政府规则中,规则中隐藏的语义从来都不是好事。群体和社区必须对规则有共同的理解,如果意义被隐瞒,他们就无法做到这一点。因此,商业和政府规则应该始终是纯粹声明性的。顺序永远不重要!

将关注点分开
让我们在这里明确一下我在说什么和我没在说什么。我并不是说指令和程序(按顺序排列的指令集)是件坏事。它们的重要性不言而喻。没有它们,我们怎么生活!

举个例子,我在上面的思想实验中,唯一有效的表达方式就是程序。我不可能用规则来表达它。我为什么还要尝试呢?规则绝不能以任何方式、形式代替程序或过程。

规则只是告诉你什么样的结果是正确的。

这样来看。没有行动、程序和过程,世界的状态就永远不会改变。我们显然不是生活在一个静止的世界里......即使我们想,也做不到。行动、程序和过程(变换)是生活的基本事实。

社区和群体的规则则有不同的作用。它们从来不会让事情发生;它们只是表达了哪些事态是允许的(可取的),或者更重要的是,哪些是不允许的(不可取的)。

规则是强加给行动的。

因此,你永远不要混淆规则和指令。你总是要明确孰是孰非。我所说的 "混淆 "具体指两件事:

  • “规则 "决不能要求执行某个动作。如果是这样,它就不是真正的规则;
  • 它是一种指令,应被视为真正的指令。(在这方面臭名昭著的是调用臭名昭著的 CRUD(创建、检索、更新、删除)字样的 "规则"。这些都是纯粹的(数据)系统操作)。

即使单个规则是以声明的方式表达的,也绝不能将其作为程序(指令集)中的一个步骤。隐含地说,将一条单独的规则包含在按顺序排列的指令集中的某个位置,会将该规则变成一条指令。

对于政策解释者和分析者来说,区分规则(陈述性)和指令(程序性)是一项重要任务。业务专家往往想告诉你如何做事,因此他们倾向于按程序说话。

如何做当然很重要。然而,同样重要的是表达所发生事情的正确性标准(规则)。

要将做什么与如何做区分开来!

指令是关于如何做:为了完成某件事情而要做的正确事情;规则是关于做什么:无论如何做都要把事情做对。

条件指示
让我们再来看几个例子。

1、在装有斧头的玻璃箱上张贴的标志:发生火灾时,请打碎玻璃。
这句话是有条件的("万一着火"),但给出了一个指令("打碎玻璃")。它要求执行一个动作。它不是一条规则。

出于同样的原因,以下所有语句都是条件指令,而不是规则:
2、如果塑料破裂,用胶带固定。

3、如果比赛对你很重要,请搭乘第一班飞机前往。

4、在投掷手榴弹之前,先拔掉保险栓。

所有指令,无论是否有条件,都有一个显著特点,那就是它们的评估顺序是不同的。假设你看到的不是一个指示牌,而是两个贴在一起的指示牌:

贴在装有斧头的玻璃箱上的标志:着火时,打碎玻璃。

电梯附近张贴的标志:发生火灾时,从楼梯离开大楼。

先执行哪条指令会有很大不同。如果你先执行前一个指令,你可能会带着满地的碎玻璃和手中的斧头离开大楼。如果你先执行后一个指令,玻璃可能不会碎,斧头也不会掉。世界的这两种状态截然不同。

规则不应该是这样的。既然规则不执行任何动作,那么你(或机器)以何种顺序读取规则就没有任何区别。它们都同样适用。

总的来说,规则只是告诉你,行动之间的世界状态是否正确,即允许(理想)或不允许(不理想)。