php 多规格设置,规格模式(Specification)

3.8.1. 目的

构建一个清晰的业务规则规范,其中每条规则都能被针对性地检查。每个规范类中都有一个称为isSatisfiedBy的方法,方法判断给定的规则是否满足规范从而返回 true 或 false。

3.8.2. 例子

3.8.3. UML Diagram

bf9f0961a76777566c1f35cda3b45687.png

3.8.4. Code

你可以在 GitHub 中找到这段代码。

Item.php

namespace DesignPatterns\Behavioral\Specification;

class Item

{

/**

* @var float

*/

private $price;

public function __construct(float $price)

{

$this->price = $price;

}

public function getPrice(): float

{

return $this->price;

}

}

SpecificationInterface.php

namespace DesignPatterns\Behavioral\Specification;

interface SpecificationInterface

{

public function isSatisfiedBy(Item $item): bool;

}

OrSpecification.php

namespace DesignPatterns\Behavioral\Specification;

class OrSpecification implements SpecificationInterface

{

/**

* @var SpecificationInterface[]

*/

private $specifications;

/**

* @param SpecificationInterface[] ...$specifications

*/

public function __construct(SpecificationInterface ...$specifications)

{

$this->specifications = $specifications;

}

/**

* 如果有一条规则符合条件,返回 true,否则返回 false

*/

public function isSatisfiedBy(Item $item): bool

{

foreach ($this->specifications as $specification) {

if ($specification->isSatisfiedBy($item)) {

return true;

}

}

return false;

}

}

PriceSpecification.php

namespace DesignPatterns\Behavioral\Specification;

class PriceSpecification implements SpecificationInterface

{

/**

* @var float|null

*/

private $maxPrice;

/**

* @var float|null

*/

private $minPrice;

/**

* @param float $minPrice

* @param float $maxPrice

*/

public function __construct($minPrice, $maxPrice)

{

$this->minPrice = $minPrice;

$this->maxPrice = $maxPrice;

}

public function isSatisfiedBy(Item $item): bool

{

if ($this->maxPrice !== null && $item->getPrice() > $this->maxPrice) {

return false;

}

if ($this->minPrice !== null && $item->getPrice() < $this->minPrice) {

return false;

}

return true;

}

}

AndSpecification.php

namespace DesignPatterns\Behavioral\Specification;

class AndSpecification implements SpecificationInterface

{

/**

* @var SpecificationInterface[]

*/

private $specifications;

/**

* @param SpecificationInterface[] ...$specifications

*/

public function __construct(SpecificationInterface ...$specifications)

{

$this->specifications = $specifications;

}

/**

* 如果有一条规则不符合条件,返回 false,否则返回 true

*/

public function isSatisfiedBy(Item $item): bool

{

foreach ($this->specifications as $specification) {

if (!$specification->isSatisfiedBy($item)) {

return false;

}

}

return true;

}

}

NotSpecification.php

namespace DesignPatterns\Behavioral\Specification;

class NotSpecification implements SpecificationInterface

{

/**

* @var SpecificationInterface

*/

private $specification;

public function __construct(SpecificationInterface $specification)

{

$this->specification = $specification;

}

public function isSatisfiedBy(Item $item): bool

{

return !$this->specification->isSatisfiedBy($item);

}

}

3.8.5. Test

Tests/SpecificationTest.php

namespace DesignPatterns\Behavioral\Specification\Tests;

use DesignPatterns\Behavioral\Specification\Item;

use DesignPatterns\Behavioral\Specification\NotSpecification;

use DesignPatterns\Behavioral\Specification\OrSpecification;

use DesignPatterns\Behavioral\Specification\AndSpecification;

use DesignPatterns\Behavioral\Specification\PriceSpecification;

use PHPUnit\Framework\TestCase;

class SpecificationTest extends TestCase

{

public function testCanOr()

{

$spec1 = new PriceSpecification(50, 99);

$spec2 = new PriceSpecification(101, 200);

$orSpec = new OrSpecification($spec1, $spec2);

$this->assertFalse($orSpec->isSatisfiedBy(new Item(100)));

$this->assertTrue($orSpec->isSatisfiedBy(new Item(51)));

$this->assertTrue($orSpec->isSatisfiedBy(new Item(150)));

}

public function testCanAnd()

{

$spec1 = new PriceSpecification(50, 100);

$spec2 = new PriceSpecification(80, 200);

$andSpec = new AndSpecification($spec1, $spec2);

$this->assertFalse($andSpec->isSatisfiedBy(new Item(150)));

$this->assertFalse($andSpec->isSatisfiedBy(new Item(1)));

$this->assertFalse($andSpec->isSatisfiedBy(new Item(51)));

$this->assertTrue($andSpec->isSatisfiedBy(new Item(100)));

}

public function testCanNot()

{

$spec1 = new PriceSpecification(50, 100);

$notSpec = new NotSpecification($spec1);

$this->assertTrue($notSpec->isSatisfiedBy(new Item(150)));

$this->assertFalse($notSpec->isSatisfiedBy(new Item(50)));

}

}

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接

我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值