Ejemplos de código del modelo de especificación (Especificación) del patrón de diseño PHP (28)

propósito

Construya una especificación clara de reglas comerciales, en la que cada regla se pueda verificar específicamente. Cada clase de especificación tiene un método llamado isSatisfiedBy, que determina si una regla dada cumple con la especificación y devuelve verdadero o falso.

Gráficos UML

★ Gestión de "clic" de la comunidad oficial de intercambio de aprendizaje avanzado PHP para organizar algunos materiales, BAT y otras empresas de primera línea tienen sistemas de conocimiento avanzados (materiales de aprendizaje relevantes y preguntas de entrevistas escritas) y no se limitan a: arquitectura distribuida, alta escalabilidad, alta Rendimiento, alta concurrencia, ajuste del rendimiento del servidor, TP6, laravel, YII2, Redis, Swoole, Swoft, Kafka, optimización de Mysql, scripts de shell, Docker, microservicios, Nginx y otros puntos de conocimiento, productos secos avanzados avanzados

Código

  • 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);
    }
}

prueba

  • Pruebas / 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)));
    }
}

El camino de crecimiento de PHP Internet Architect * La guía definitiva para "patrones de diseño"

PHP Internet Architect 50K Growth Guide + Guía de resolución de problemas de la industria (actualización continua)

Entrevista con 10 empresas, obtenga 9 ofertas, preguntas de la entrevista PHP en 2020

★ Si le gusta mi artículo y desea comunicarse y aprender con desarrolladores más experimentados, obtenga más asesoría técnica y orientación relacionada con entrevistas con grandes fábricas, bienvenido a unirse a nuestro grupo, contraseña: phpzh (número de Junyang 856460874).

El último tutorial avanzado de PHP en 2020, ¡serie completa!

Si el contenido es bueno, espero que todos te apoyen y animen a dar un like / like, y bienvenidos a comunicarnos juntos; además, si tienes alguna duda, puedes sugerir lo que quieres ver en los comentarios.

Supongo que te gusta

Origin blog.csdn.net/weixin_43814458/article/details/108680614
Recomendado
Clasificación