📘 Provides specifications following the paper by Eric Evans and Martin Fowler.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github
.travis
src
test
.codeclimate.yml
.editorconfig
.gitattributes
.gitignore
.php_cs
.travis.yml
LICENSE
Makefile
README.md
composer.json
composer.lock
infection.json
phpstan.neon

README.md

specification

Build Status codecov Latest Stable Version Total Downloads

Provides specifications following the paper by Eric Evans and Martin Fowler, also see Wikipedia: Specification Pattern.

Installation

Run

$ composer require localheinz/specification

Usage

SpecificationInterface

Implement Localheinz\Specification\SpecificationInterface in your specifications:

namespace Foo\Bar;

use Localheinz\Specification\SpecificationInterface;

class IsInstanceOfStdClass implements SpecificationInterface
{
    public function isSatisfiedBy($candidate): bool
    {
        return $candidate instanceof \stdClass;
    }
}

class HasFooProperty implements SpecificationInterface
{
    public function isSatisfiedBy($candidate): bool
    {
        return property_exists($candidate, 'foo');
    }
}

class HasBarProperty implements SpecificationInterface
{
    public function isSatisfiedBy($candidate): bool
    {
        return property_exists($candidate, 'bar');
    }
}

AndSpecification

Use Localheinz\Specification\AndSpecification to compose a specification from specifications which all need to be satisfied:

use Localheinz\Specification\AndSpecification;
use Localheinz\Specification\Test\Fixture;

$specification = new AndSpecification(
    new Fixture\Specification\IsInstanceOfStdClass(),
    new Fixture\Specification\HasFooProperty(),
    new Fixture\Specification\HasBarProperty()
);

$candidate = new \stdClass();

$candidate->foo = 9000;
$candidate->bar = 'Hello, my name is Jane';

$specification->isSatisfiedBy($candidate); // true

OrSpecification

Use Localheinz\Specification\OrSpecification to compose a specification from specifications where only one needs to be satisfied:

use Localheinz\Specification\OrSpecification;
use Localheinz\Specification\Test\Fixture;

$specification = new OrSpecification(
    new Fixture\Specification\IsInstanceOfStdClass(),
    new Fixture\Specification\HasFooProperty(),
    new Fixture\Specification\HasBarProperty()
);

$candidate = new \stdClass();

$specification->isSatisfiedBy($candidate); // true

NotSpecification

Use Localheinz\Specification\NotSpecification to compose a specification from specifications where none should be satisfied:

use Localheinz\Specification\NotSpecification;
use Localheinz\Specification\Test\Fixture;

$specification = new NotSpecification(
    new Fixture\Specification\IsInstanceOfStdClass(),
    new Fixture\Specification\HasFooProperty(),
    new Fixture\Specification\HasBarProperty()
);

$candidate = new \SplObjectStorage();

$specification->isSatisfiedBy($candidate); // true

Mix and match

Mix and match all of the specifications to your need:

use Localheinz\Specification\AndSpecification;
use Localheinz\Specification\NotSpecification;
use Localheinz\Specification\OrSpecification;
use Localheinz\Specification\Test\Fixture;

$specification = new AndSpecification(
    new NotSpecification(new Fixture\Specification\IsInstanceOfStdClass()),
    new OrSpecification(
        new Fixture\Specification\HasFooProperty(),
        new Fixture\Specification\HasBarProperty()
    )
);

class Baz
{
    public $foo;
}

$candidate = new Baz();

$specification->isSatisfiedBy($candidate); // true

Contributing

Please have a look at CONTRIBUTING.md.

Code of Conduct

Please have a look at CODE_OF_CONDUCT.md.

License

This package is licensed using the MIT License.