规格模式

<?php

// 每个规范类中都有一个称为 isSatisfiedBy 的方法,
// 方法判断给定的规则是否满足规范从而返回 true 或 false。
// php 技术群:781742505

declare(strict_types=1);

class Item
{
    private $price;

    public function __construct(float $price)
    {
        $this->price = $price;
    }

    public function getPrice(): float
    {
        return $this->price;
    }
}

interface Specification
{
    public function isSatisfiedBy(Item $item): bool;
}

class OrSpecification implements Specification
{
    private $specifications;

    public function __construct(Specification ...$specifications)
    {
        $this->specifications = $specifications;
    }

    public function isSatisfiedBy(Item $item): bool
    {
        foreach ($this->specifications as $specification) {
            if ($specification->isSatisfiedBy($item)) {
                return true;
            }
        }
        return false;
    }
}

class PriceSpecification implements Specification
{
    /**
     * @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;
    }
}

class AndSpecification implements Specification
{
    /**
     * @var Specification[]
     */
    private $specifications;

    /**
     * @param Specification[] ...$specifications
     */
    public function __construct(Specification ...$specifications)
    {
        $this->specifications = $specifications;
    }

    /**
     * if at least one specification is false, return false, else return true.
     */
    public function isSatisfiedBy(Item $item): bool
    {
        foreach ($this->specifications as $specification) {
            if (!$specification->isSatisfiedBy($item)) {
                return false;
            }
        }

        return true;
    }
}

class NotSpecification implements Specification
{
    /**
     * @var Specification
     */
    private $specification;

    public function __construct(Specification $specification)
    {
        $this->specification = $specification;
    }

    public function isSatisfiedBy(Item $item): bool
    {
        return !$this->specification->isSatisfiedBy($item);
    }
}

$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)));



$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)));




$spec1 = new PriceSpecification(50, 100);
$notSpec = new NotSpecification($spec1);

$this->assertTrue($notSpec->isSatisfiedBy(new Item(150)));
$this->assertFalse($notSpec->isSatisfiedBy(new Item(50)));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值