kanel/specification2

Specification设计模式的实现

1.0.0 2017-07-13 12:38 UTC

This package is not auto-updated.

Last update: 2024-09-18 22:00:46 UTC


README

build

Specification设计模式

这是我对“Specification”设计模式的实现。它比原始版本更简单、更直接。

它还允许组合多个不同参数类型的Specification。

此模式的目的是为了有独立的逻辑类,以便在不重写和维护不同位置的条件的情况下进行条件组合。

以下是该包的详细“如何使用”指南

创建一个Specification

创建一个实现了SpecificationInterface的类,并包含你的逻辑

以下是一个检查产品和客户不同方面的规范列表的基本示例

一个检查产品是否可用的类

    class IsProductAvaialble implement SpecificationInterface
    {
        protected $product;
        protected $neededQuantity;
        
        public function __construc(Product $product, $neededQuantity = 1)
        {
            $this->product = $product;
            $this->neededQuantity = $neededQuantity;
        }
        
        public function isValid(): bool
        {
            //here your code logic that uses the data set in the construct and returns a boolean
        }
    }

一个检查产品是否可以寄送给客户的类

    class IsProductShipableForCustomer implement SpecificationInterface
    {
        protected $product;
        protected $customer;
        
        public function __construc(Product $product, Customer $customer)
        {
            $this->product = $product;
            $this->customer = $customer;
        }
        
        public function isValid(): bool
        {
            //doing the logic to check if the product is avaialble in the customer's country 
        }
    }

一个检查产品是否为特殊产品的类(特殊产品应始终(神奇地?)有库存)

    class IsASpecialProduct implement SpecificationInterface
    {
        protected $product;
        
        public function __construc(Product $product)
        {
            $this->product = $product;
        }
        
        public function isValid(): bool
        {
            //doing the logic to check if the product is special 
        }
    }

一个检查客户是否不在黑名单上的类

    class IsCustomerBlackListed implement SpecificationInterface
    {
        protected $customer;
        
        public function __construc(Customer $customer)
        {
            $this->customer = $customer;
        }
        
        public function isValid(): bool
        {
            //doing the logic to checks if the customer is banned
        }
    }

所有可用的运算符

2.1 - isSatisfiedBy

Specification模式的三种入口点之一。
必须在任何运算符之前使用。
如果在运算符之后使用,将抛出WrongUsageException异常

示例

    $specification = (new Specification())->isSatisfiedBy(new IsProductAvaialble($product));
     
     if ($specification->isValid()) {
        ...
     }

2.2 - isSatisfiedByAll

Specification模式的第二种可能的入口点。
检查发送的所有Specification是否有效(相当于链式和运算符)
必须在任何运算符之前使用。
如果在运算符之后使用,将抛出WrongUsageException异常

示例

    $specification = (new Specification())->isSatisfiedByAll(
        new IsProductAvaialble($product), 
        new IsProductShipableForCustome($product, $customer)
    );
    
    if ($specification->isValid()) {
        ...
    }

2.3 - isSatisfiedByAny

Specification模式的第三种和最后一个可能的起始点。
检查发送的Specification中是否有有效的一个(相当于链式或运算符)
必须在任何运算符之前使用。
如果在运算符之后使用,将抛出WrongUsageException异常

示例

    $specification = (new Specification())->isSatisfiedByAny(
        new IsProductAvaialble($product), 
        new IsASpecialProduct($product)
    );
    
    if ($specification->isValid()) {
        ...
    }

2.4 - and运算符

在之前设置的规范中添加一个'&&'条件
不能首先使用,否则将抛出WrongUsageException异常

示例

    $specification = (new Specification())
        ->isSatisfiedBy(new IsProductAvaialble($product))
        ->and(new IsProductShipableForCustomer($product, $customer))
        ...
    ;
    
    if ($specification->isValid()) {
       ...
    }

2.5 - andNot运算符

在之前设置的规范中添加一个'&& !'条件
不能首先使用,否则将抛出WrongUsageException异常

示例

    $specification = (new Specification())
        ->isSatisfiedBy(new IsProductAvaialble($product))
        ->and(new IsProductShipableForCustomer($product, $customer))
        ->andNot(new IsCustomerBlackListed($customer)
        ...
    ;
    
    if ($specification->isValid()) {
       ...
    }

2.6 - or运算符

在之前设置的规范中添加一个'||'条件
不能首先使用,否则将抛出WrongUsageException异常

示例

    $specification = (new Specification())
       ->isSatisfiedBy(new IsProductAvaialble($product))
       ->or(new IsASpecialProduc($product))
       ...
    ;
                   
    
    if ($specification->isValid()) {
       ...
    }

2.7 - orNot运算符

在之前设置的规范中添加一个'|| !'条件
不能首先使用,否则将抛出WrongUsageException异常

示例

    $specification = (new Specification())
       ->isSatisfiedBy(new IsProductAvaialble($product))
       ->orNot(new IsASpecialProduc($product))
    ;
                   
    
    if ($specification->isValid()) {
       ...
    }

2.7 - xor运算符

在之前设置的规范中添加一个'xor'条件
不能首先使用,否则将抛出WrongUsageException异常

示例

    $specification = (new Specification())
       ->isSatisfiedBy(new IsProductAvaialble($product))
       ->xor(new IsASpecialProduc($product))
    ;
                   
    
    if ($specification->isValid()) {
       ...
    }

2.7 - xorNot运算符

在之前设置的规范中添加一个'xor !'条件
不能首先使用,否则将抛出WrongUsageException异常

示例

    $specification = (new Specification())
       ->isSatisfiedBy(new IsProductAvaialble($product))
       ->xorNot(new IsASpecialProduc($product))
    ;
                   
    
    if ($specification->isValid()) {
       ...
    }

3- 组合

规范可以组合使用

示例

    $specification = (new Specification())
        ->isSatisfiedBy(new IsProductShipableForCustomer($product, $customer))
        ->and(
            (new Specification())
                ->isSatisfiedBy(new IsProductAvaialble($product))
                ->or(new IsASpecialProduct($product))
        )
    ;
    
    if ($specification->isValid()) {
       ...
    }