https://github.com/vjik/specification
PHP implementation of "Specification" pattern
https://github.com/vjik/specification
pattern php specification specification-pattern specifications
Last synced: 6 months ago
JSON representation
PHP implementation of "Specification" pattern
- Host: GitHub
- URL: https://github.com/vjik/specification
- Owner: vjik
- License: bsd-3-clause
- Created: 2024-11-20T18:45:31.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2024-11-21T12:46:38.000Z (about 1 year ago)
- Last Synced: 2025-01-25T17:43:05.985Z (about 1 year ago)
- Topics: pattern, php, specification, specification-pattern, specifications
- Language: PHP
- Homepage:
- Size: 13.7 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Specification Pattern
[](https://packagist.org/packages/vjik/specification)
[](https://packagist.org/packages/vjik/specification)
[](https://github.com/vjik/specification/actions/workflows/build.yml)
[](https://coveralls.io/github/vjik/specification)
[](https://dashboard.stryker-mutator.io/reports/github.com/vjik/specification/master)
[](https://shepherd.dev/github/vjik/specification)
[](https://github.com/vjik/specification/actions?query=workflow%3A%22static+analysis%22)
[](https://shepherd.dev/github/vjik/specification)
The package provides PHP implementation of
"[Specification](https://designpatternsphp.readthedocs.io/en/latest/Behavioral/Specification/README.html)"
software design pattern:
- interface `SpecificationInterface` and abstract `BaseSpecification` to create user specifications;
- composite specifications `AndSpecification` and `OrSpecification`;
- negation specification `NotSpecification`.
## Requirements
- PHP 8.2 or higher.
## Installation
The package could be installed with [composer](https://getcomposer.org/download/):
```shell
composer require vjik/specification
```
## General usage
You can create your own specifications by inheriting from the `BaseSpecification` class:
```php
use Vjik\Specification\BaseSpecification;
/**
* @template T as User
* @template-extends BaseSpecification
*/
final class UserIsAdultSpecification extends BaseSpecification
{
/**
* @param T $value
*/
public function isSatisfiedBy(mixed $value): bool
{
return $value->age >= 18;
}
}
$specification = new UserIsAdultSpecification();
// true or false
$specification->isSatisfiedBy($user);
// throws an exception if user is not adult
$specification->satisfiedBy($user);
```
> We recommend use static analysis tools like [Psalm](https://psalm.dev) and [PHPStan](https://phpstan.org)
> to improve code quality.
### Built-in specifications
You can combine specifications using composite specifications:
```php
use Vjik\Specification\AndSpecification;
use Vjik\Specification\OrSpecification;
// User is adult AND active
$isActiveAdultUserSpecification = new AndSpecification([
new UserIsAdultSpecification(),
new UserIsActiveSpecification(),
]);
// User is adult OR user with parents
$userHasAccessSpecification = new OrSpecification([
new UserIsAdultSpecification(),
new UserWithParentsSpecification(),
]);
```
Also, you can use negation specification:
```php
use Vjik\Specification\NotSpecification;
// User is not adult
$userIsNotAdultSpecification = new NotSpecification(
new UserIsAdultSpecification()
);
```
### Static analysis compatible
Static analysis tools like [Psalm](https://psalm.dev) and [PHPStan](https://phpstan.org) helps you to avoid mistakes.
For example, Psalm issues:
```php
$userIsAdultSpecification = new UserIsAdultSpecification();
// ERROR: InvalidArgument Argument 1 of UserIsAdultSpecification::isSatisfiedBy expects User, but 'test' provided
$userIsAdultSpecification->isSatisfiedBy('test');
// ERROR: InvalidArgument Argument 1 of UserIsAdultSpecification::satisfiedBy expects User, but 'test' provided
$userIsAdultSpecification->satisfiedBy('test');
// ERROR: InvalidArgument Incompatible types found for T (must have only one of User, Post)
$isActiveAdultUserSpecification = new AndSpecification([
new UserIsAdultSpecification(),
new PostIsActiveSpecificaion(),
]);
```
## Documentation
- [Internals](docs/internals.md)
If you have any questions or problems with this package, use [author telegram chat](https://t.me/predvoditelev_chat)
for communication.
## License
The `vjik/specification` is free software. It is released under the terms of the BSD License.
Please see [`LICENSE`](./LICENSE.md) for more information.