规格模式 Specification Pattern
定义#
规格模式是组合模式的一种扩展。这是一种结构型设计模式。
通过条件关系(与、或、非)组合,来处理查询或过滤,而不是使用逻辑判断语句来处理,可以使逻辑更加简单。这里的每个条件都是一个规格,多个规格串联形成一个组合式的规格。
设计的原则和思想#
- 解耦的是业务逻辑和逻辑条件。
- 不变部分是逻辑条件,变化部分是业务逻辑。
- 核心思想是通过逻辑运算的方式简化和定制业务逻辑。
一句话概括设计模式#
组合模式(逻辑规格书和整体规格书的关系就是局部和整体的关系) + 策略模式(一个规则书是一个策略)。
结构中包含的角色#
- Specification 抽象规格书
- CompositeSpecification 组合规格书
- AndSpecification 逻辑条件 “与” 规划书
- 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);
何时使用#
- 筛选数据。
- 查询数据。
实际应用场景#
- 数据过滤。
- 数据库 SQL 条件组合。
推荐文章: