PHP 设计模式系列之 specification规格模式
程序员文章站
2022-06-21 14:21:01
1、模式定义
规格模式是组合模式的一种扩展,在框架性开发中使用较多(项目级开发很少使用),这里做一个简单的介绍。
规格模式(specification)可以认为是组...
1、模式定义
规格模式是组合模式的一种扩展,在框架性开发中使用较多(项目级开发很少使用),这里做一个简单的介绍。
规格模式(specification)可以认为是组合模式的一种扩展。有时项目中某些条件决定了业务逻辑,这些条件就可以抽离出来以某种关系(与、或、非)进行组合,从而灵活地对业务逻辑进行定制。另外,在查询、过滤等应用场合中,通过预定义多个条件,然后使用这些条件的组合来处理查询或过滤,而不是使用逻辑判断语句来处理,可以简化整个实现逻辑。
这里的每个条件就是一个规格,多个规格/条件通过串联的方式以某种逻辑关系形成一个组合式的规格。
2、uml类图
3、示例代码
item.php
<?php namespace designpatterns\behavioral\specification; class item { protected $price; /** * an item must have a price * * @param int $price */ public function __construct($price) { $this->price = $price; } /** * get the items price * * @return int */ public function getprice() { return $this->price; } }
specificationinterface.php
<?php namespace designpatterns\behavioral\specification; /** * 规格接口 */ interface specificationinterface { /** * 判断对象是否满足规格 * * @param item $item * * @return bool */ public function issatisfiedby(item $item); /** * 创建一个逻辑与规格(and) * * @param specificationinterface $spec */ public function plus(specificationinterface $spec); /** * 创建一个逻辑或规格(or) * * @param specificationinterface $spec */ public function either(specificationinterface $spec); /** * 创建一个逻辑非规格(not) */ public function not(); }
abstractspecification.php
<?php namespace designpatterns\behavioral\specification; /** * 规格抽象类 */ abstract class abstractspecification implements specificationinterface { /** * 检查给定item是否满足所有规则 * * @param item $item * * @return bool */ abstract public function issatisfiedby(item $item); /** * 创建一个新的逻辑与规格(and) * * @param specificationinterface $spec * * @return specificationinterface */ public function plus(specificationinterface $spec) { return new plus($this, $spec); } /** * 创建一个新的逻辑或组合规格(or) * * @param specificationinterface $spec * * @return specificationinterface */ public function either(specificationinterface $spec) { return new either($this, $spec); } /** * 创建一个新的逻辑非规格(not) * * @return specificationinterface */ public function not() { return new not($this); } }
plus.php
<?php namespace designpatterns\behavioral\specification; /** * 逻辑与规格(and) */ class plus extends abstractspecification { protected $left; protected $right; /** * 在构造函数中传入两种规格 * * @param specificationinterface $left * @param specificationinterface $right */ public function __construct(specificationinterface $left, specificationinterface $right) { $this->left = $left; $this->right = $right; } /** * 返回两种规格的逻辑与评估 * * @param item $item * * @return bool */ public function issatisfiedby(item $item) { return $this->left->issatisfiedby($item) && $this->right->issatisfiedby($item); } }
either.php
<?php namespace designpatterns\behavioral\specification; /** * 逻辑或规格 */ class either extends abstractspecification { protected $left; protected $right; /** * 两种规格的组合 * * @param specificationinterface $left * @param specificationinterface $right */ public function __construct(specificationinterface $left, specificationinterface $right) { $this->left = $left; $this->right = $right; } /** * 返回两种规格的逻辑或评估 * * @param item $item * * @return bool */ public function issatisfiedby(item $item) { return $this->left->issatisfiedby($item) || $this->right->issatisfiedby($item); } }
not.php
<?php namespace designpatterns\behavioral\specification; /** * 逻辑非规格 */ class not extends abstractspecification { protected $spec; /** * 在构造函数中传入指定规格 * * @param specificationinterface $spec */ public function __construct(specificationinterface $spec) { $this->spec = $spec; } /** * 返回规格的相反结果 * * @param item $item * * @return bool */ public function issatisfiedby(item $item) { return !$this->spec->issatisfiedby($item); } }
pricespecification.php
<?php namespace designpatterns\behavioral\specification; /** * 判断给定item的价格是否介于最小值和最大值之间的规格 */ class pricespecification extends abstractspecification { protected $maxprice; protected $minprice; /** * 设置最大值 * * @param int $maxprice */ public function setmaxprice($maxprice) { $this->maxprice = $maxprice; } /** * 设置最小值 * * @param int $minprice */ public function setminprice($minprice) { $this->minprice = $minprice; } /** * 判断给定item的定价是否在最小值和最大值之间 * * @param item $item * * @return bool */ public function issatisfiedby(item $item) { if (!empty($this->maxprice) && $item->getprice() > $this->maxprice) { return false; } if (!empty($this->minprice) && $item->getprice() < $this->minprice) { return false; } return true; } }
4、测试代码
tests/specificationtest.php
<?php namespace designpatterns\behavioral\specification\tests; use designpatterns\behavioral\specification\pricespecification; use designpatterns\behavioral\specification\item; /** * specificationtest 用于测试规格模式 */ class specificationtest extends \phpunit_framework_testcase { public function testsimplespecification() { $item = new item(100); $spec = new pricespecification(); $this->asserttrue($spec->issatisfiedby($item)); $spec->setmaxprice(50); $this->assertfalse($spec->issatisfiedby($item)); $spec->setmaxprice(150); $this->asserttrue($spec->issatisfiedby($item)); $spec->setminprice(101); $this->assertfalse($spec->issatisfiedby($item)); $spec->setminprice(100); $this->asserttrue($spec->issatisfiedby($item)); } public function testnotspecification() { $item = new item(100); $spec = new pricespecification(); $not = $spec->not(); $this->assertfalse($not->issatisfiedby($item)); $spec->setmaxprice(50); $this->asserttrue($not->issatisfiedby($item)); $spec->setmaxprice(150); $this->assertfalse($not->issatisfiedby($item)); $spec->setminprice(101); $this->asserttrue($not->issatisfiedby($item)); $spec->setminprice(100); $this->assertfalse($not->issatisfiedby($item)); } public function testplusspecification() { $spec1 = new pricespecification(); $spec2 = new pricespecification(); $plus = $spec1->plus($spec2); $item = new item(100); $this->asserttrue($plus->issatisfiedby($item)); $spec1->setmaxprice(150); $spec2->setminprice(50); $this->asserttrue($plus->issatisfiedby($item)); $spec1->setmaxprice(150); $spec2->setminprice(101); $this->assertfalse($plus->issatisfiedby($item)); $spec1->setmaxprice(99); $spec2->setminprice(50); $this->assertfalse($plus->issatisfiedby($item)); } public function testeitherspecification() { $spec1 = new pricespecification(); $spec2 = new pricespecification(); $either = $spec1->either($spec2); $item = new item(100); $this->asserttrue($either->issatisfiedby($item)); $spec1->setmaxprice(150); $spec2->setmaxprice(150); $this->asserttrue($either->issatisfiedby($item)); $spec1->setmaxprice(150); $spec2->setmaxprice(0); $this->asserttrue($either->issatisfiedby($item)); $spec1->setmaxprice(0); $spec2->setmaxprice(150); $this->asserttrue($either->issatisfiedby($item)); $spec1->setmaxprice(99); $spec2->setmaxprice(99); $this->assertfalse($either->issatisfiedby($item)); } }
以上内容是小编给大家分享的php 设计模式系列之 specification规格模式,希望本文分享能够帮助大家。
上一篇: C# 无限级分类的实现