innmind / specification
允许组合规范树型的接口
4.1.0
2024-07-13 14:45 UTC
Requires
- php: ~8.1
Requires (Dev)
- innmind/coding-standard: ~2.0
- vimeo/psalm: ~4.4
README
包含允许组合规范树型接口的库。由于您可能想要为测试的对象进行类型提示,接口不强制实现 isSatisfiedBy
方法,您需要自己创建此类方法。
此处的目标是拥有一个接口集合,以便可以轻松地组合规范,并且之后可以分解。
分解部分在您想要将规范转换为,比如说,一个 doctrine 查询(或任何您想要的)时很有用。
实现示例
use Innmind\Specification\{ Specification, Composite, Operator, Not, Comparator, Sign, }; class User { public $name; public function __construct(string $name) { $this->name = $name; } } class AndSpecification implements Composite { private $left; private $right; public function __construct(Specification $left, Specification $right) { $this->left = $left; $this->right = $right; } public function left(): Specification { return $this->left; } public function operator(): Operator { return Operator::and; } public function right(): Specification { return $this->right; } public function isSatisfiedBy(User $user): bool { return $this->left->isSatisfiedBy($user) && $this->right->isSatisfiedBy($user); } } class OrSpecification implements Composite { private $left; private $right; public function __construct(Specification $left, Specification $right) { $this->left = $left; $this->right = $right; } public function left(): Specification { return $this->left; } public function operator(): Operator { return Operator::or; } public function right(): Specification { return $this->right; } public function isSatisfiedBy(User $user): bool { return $this->left->isSatisfiedBy($user) || $this->right->isSatisfiedBy($user); } } class NotSpecification implements Not { private $specification; public function __construct(Specification $specification) { $this->specification = $specification; } public function specification(): Specification { return $this->specification; } public function isSatisfiedBy(User $user): bool { return !$this->specification->isSatisfiedBy($user); } } class NameSpecification implements Comparator { private $name; public function __construct(string $name) { $this->name = $name; } public function and(Specification $specification): Composite { return new AndSpecification($this, $specification); } public function or(Specification $specification): Composite { return new OrSpecification($this, $specification); } public function not(): Not { return new NotSpecification($this); } public function property(): string { return 'name'; } public function sign(): Sign { return Sign::equality; } public function value() { return $this->name; } public function isSatisfiedBy(User $user): bool { return $user->name === $this->name; } } $spec = (new NameSpecification('John')) ->or(new NameSpecification('Doe')) ->or((new NameSpecification('John Doe'))->not()); $spec->isSatisfiedBy(new User('John')); //true $spec->isSatisfiedBy(new User('Doe')); //true $spec->isSatisfiedBy(new User('John Doe')); //false $spec->isSatisfiedBy(new User('42')); //true
对象 $spec
可以轻松分解以创建 SQL 查询的给定 WHERE
语句:WHERE name = "John" or name = "Doe" or name != "John Doe"
。