美文网首页
PHP设计模式之规格模式(Specification)代码实例大

PHP设计模式之规格模式(Specification)代码实例大

作者: 八重樱勿忘 | 来源:发表于2020-09-19 14:25 被阅读0次

    目的

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

    UML图

    ★官方PHP高级学习交流社群「点击」管理整理了一些资料,BAT等一线大厂进阶知识体系备好(相关学习资料以及笔面试题)以及不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货

    代码

    • Item.php
    
    <?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
    
    <?php
    
    namespace DesignPatterns\Behavioral\Specification;
    
    interface SpecificationInterface
    {
        public function isSatisfiedBy(Item $item): bool;
    }
    
    • OrSpecification.php
    
    <?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
    
    <?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
    
    <?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
    
    <?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);
        }
    }
    

    测试

    • Tests/SpecificationTest.php
    
    <?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)));
        }
    }
    

    PHP 互联网架构师成长之路*「设计模式」终极指南

    PHP 互联网架构师 50K 成长指南+行业问题解决总纲(持续更新)

    面试10家公司,收获9个offer,2020年PHP 面试问题

    ★如果喜欢我的文章,想与更多资深开发者一起交流学习的话,获取更多大厂面试相关技术咨询和指导,欢迎加入我们的群啊,暗号:phpzh

    2020年最新PHP进阶教程,全系列!

    内容不错的话希望大家支持鼓励下点个赞/喜欢,欢迎一起来交流;另外如果有什么问题 建议 想看的内容可以在评论提出

    相关文章

      网友评论

          本文标题:PHP设计模式之规格模式(Specification)代码实例大

          本文链接:https://www.haomeiwen.com/subject/ctbeyktx.html