2017 © Pedro Peláez
 

library specification

Interfaces allowing to compose a tree of specifications

image

innmind/specification

Interfaces allowing to compose a tree of specifications

  • Saturday, March 19, 2016
  • by Baptouuuu
  • Repository
  • 1 Watchers
  • 0 Stars
  • 1,125 Installations
  • PHP
  • 8 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 3 Versions
  • 15 % Grown

The README.md

Specification

Build Status Type Coverage, (*1)

Library containing interfaces allowing to compose a tree of specification. As you may want to type hint the object you to test against, the interfaces does not enforce a method isSatisfiedBy, it will be up to you to create such method., (*2)

The goal here is to have a set of interfaces so a specification can be composed easily, and decomposed afterward., (*3)

The decomposition part is useful in the case you want to translate your specification into, let's say, a doctrine query (or anything you wish)., (*4)

Implementation example

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

The object $spec could be easily decomposed to create the given WHERE statement of a sql query: WHERE name = "John" or name = "Doe" or name != "John Doe"., (*5)

The Versions

19/03 2016

dev-master

9999999-dev http://github.com/Innmind/Specification

Interfaces allowing to compose a tree of specifications

  Sources   Download

MIT

The Requires

  • php >=7.0

 

specification ddd

19/03 2016

1.0.0

1.0.0.0 http://github.com/Innmind/Specification

Interfaces allowing to compose a tree of specifications

  Sources   Download

MIT

The Requires

  • php >=7.0

 

specification ddd

19/03 2016

dev-develop

dev-develop http://github.com/Innmind/Specification

Interfaces allowing to compose a tree of specifications

  Sources   Download

MIT

The Requires

  • php >=7.0

 

specification ddd