规格模式 Specification Pattern

未匹配的标注

定义

   规格模式是组合模式的一种扩展。这是一种结构型设计模式。
   通过条件关系(与、或、非)组合,来处理查询或过滤,而不是使用逻辑判断语句来处理,可以使逻辑更加简单。这里的每个条件都是一个规格,多个规格串联形成一个组合式的规格。

设计的原则和思想

  1. 解耦的是业务逻辑和逻辑条件。
  2. 不变部分是逻辑条件,变化部分是业务逻辑。
  3. 核心思想是通过逻辑运算的方式简化和定制业务逻辑。

一句话概括设计模式

组合模式(逻辑规格书和整体规格书的关系就是局部和整体的关系) + 策略模式(一个规则书是一个策略)

结构中包含的角色

  1. Specification 抽象规格书
  2. CompositeSpecification 组合规格书
  3. AndSpecification 逻辑条件“与”规划书
  4. BizSpecification 业务规格书

最小可表达代码

// 抽象规格书
interface Specification {
    public function isSatisfiedBy($candidate);
    public function and(Specification $spec);
}

// 组合规格书
abstract class CompositeSpecification implements Specification
{
    public function and(Specification $spec)
    {
        return new AndSpecification($this, $spec);
    }
}

// 与规划书
class AndSpecification extends CompositeSpecification
{
    private $left;
    private $right;

    public function __construct(Specification $left, Specification $right)
    {
        $this->left = $left;
        $this->right = $right;
    }

    public function isSatisfiedBy($candidate)
    {
        return $this->left->isSatisfiedBy($candidate) && $this->right->isSatisfiedBy($candidate);
    }
}

// 年龄规划书(BizSpecification)
class AgeSpecification extends CompositeSpecification
{
    public function isSatisfiedBy($student)
    {
        return $student['age'] > 18;
    }
}

// 性别规划书(BizSpecification)
class SexSpecification extends CompositeSpecification
{
    public function isSatisfiedBy($student)
    {
        return $student['sex'] == '女';
    }
}

$students = [
    ['name' => '张3','age' => 18, 'sex' => '男'],
    ['name' => '张4','age' => 20, 'sex' => '女'],
    ['name' => '张5','age' => 20, 'sex' => '男'],
];
$ageSpecification = new AgeSpecification();
$sexSpecification = new SexSpecification();
$studentSpecification = $ageSpecification->and($sexSpecification);
$data = [];
foreach ($students as $student) {
    if ($studentSpecification->isSatisfiedBy($student)) {
        $data[] = $student;
    }
}
var_dump($data);

何时使用

  1. 筛选数据。
  2. 查询数据。

实际应用场景

  1. 数据过滤。
  2. 数据库SQL条件组合。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~