frontastic/rulerz

规格模式的强大实现

资助包维护!
Patreon

0.22.0 2023-09-19 08:08 UTC

This package is auto-updated.

Last update: 2024-09-19 10:55:53 UTC


README

规格模式的核心思想是将如何匹配候选对象的表达与要匹配的候选对象本身分离开来。

规格,由 Eric Evans 和 Martin Fowler 解释

RulerZ 是一种 PHP 实现的 规格模式,它侧重于三个主要方面:

  • 一个简单且 数据无关的 领域特定语言,用于定义业务规则和规格,
  • 检查候选对象是否满足规格的能力,
  • 过滤或查询任何数据源以仅检索符合规格的候选对象的能力。

简介

业务规则可以使用专用语言以文本形式编写,这种语言非常接近 SQL,在这种情况下,我们将其称为 规则,或者它们可以封装在单个类中,并称为 规格

一旦编写了规则(或规格),就可以用来检查单个候选对象是否满足它,或者直接查询数据源。

以下数据源是原生支持的:

  • 数组数组,
  • 对象数组。

并且为这些数据源中的每一个都提供了额外的库支持

杀手级功能:当与 Doctrine、Pomm 或 Elasticsearch 一起工作时,RulerZ 能够直接在查询中转换规则,而不需要事先获取数据。

这很酷,但我为什么需要它呢?

首先,您可以使用一种专门的、简单的语言来 表达业务规则。然后,这些业务规则可以被 封装 在规格类中,重用和组合以形成更复杂的规则。规格现在是 可重用可测试 的。最后但同样重要的是,这些规则可以用来检查候选对象是否满足它,也可以用来 过滤任何数据源

如果您仍然需要说服,您可以在 这篇文章 中阅读整个推理过程。

快速使用

作为一个快速概述,我们建议您查看一个示例,该示例演示了如何操作一个简单的规则和多个数据源。

1. 编写一个规则

以下规则描述了“排名靠前的女选手”(基本上,是指得分超过9000分的女选手)。

$highRankFemalesRule = 'gender = "F" and points > 9000';

2. 定义数据源

我们有以下数据源

// a Doctrine QueryBuilder
$playersQb = $entityManager
    ->createQueryBuilder()
    ->select('p')
    ->from('Entity\Player', 'p');

// or an array of arrays
$playersArr = [
    ['pseudo' => 'Joe',   'gender' => 'M', 'points' => 2500],
    ['pseudo' => 'Moe',   'gender' => 'M', 'points' => 1230],
    ['pseudo' => 'Alice', 'gender' => 'F', 'points' => 9001],
];

// or an array of objects
$playersObj = [
    new Player('Joe',   'M', 40, 2500),
    new Player('Moe',   'M', 55, 1230),
    new Player('Alice', 'F', 27, 9001),
];

3. 使用规则查询数据源

对于我们的数据源,检索结果就像调用filter方法一样简单。

// converts the rule in DQL and makes a single query to the DB
$highRankFemales = $rulerz->filter($playersQb, $highRankFemalesRule);
// filters the array of arrays
$highRankFemales = $rulerz->filter($playersArr, $highRankFemalesRule);
// filters the array of objects
$highRankFemales = $rulerz->filter($playersObj, $highRankFemalesRule);

3. (bis) 检查候选者是否符合规则

给定一个候选者,检查它是否符合规则相当于调用satisfies方法。

$isHighRankFemale = $rulerz->satisfies($playersObj[0], $highRankFemalesRule);

进一步了解

查看文档,了解RulerZ能为您做什么。

许可协议

此库受MIT许可协议约束。