Skip to content

Latest commit

 

History

History
172 lines (126 loc) · 5.25 KB

README-ja.md

File metadata and controls

172 lines (126 loc) · 5.25 KB

English | 日本語

PHP Specification

test coverage

これはPHPで仕様パターンを実装するのを手助けするライブラリです。
メモリー上での検証、メモリー上およびORMでの選択、および仕様の合成を提供します。

インストール方法

composer require ngmy/specification

使用方法

仕様の作成およびメモリー上での検証・選択

AbstractSpecificationクラスを継承しあなたの仕様クラスを作成します。

そしてisSatisfiedByメソッドを実装します。
このメソッドに仕様を満たす条件を記述します。

さらに@extendsアノテーションでisSatisfiedByメソッドが期待するオブジェクトの型を記述しておくと静的解析が捗ります。

<?php

declare(strict_types=1);

use Ngmy\Specification\AbstractSpecification;

/**
 * 人気ユーザー仕様。
 *
 * @extends AbstractSpecification<User>
 */
class PopularUserSpecification extends AbstractSpecification
{
    /**
     * {@inheritdoc}
     */
    public function isSatisfiedBy($candidate): bool
    {
        return $candidate->getVotes() > 100;
    }
}

isSatisfiedByメソッドに検証したいオブジェクトを渡して呼び出すことで、 そのオブジェクトが仕様を満たすかどうかを検証できます。

$spec = new PopularUserSpecification();
$spec->isSatisfiedBy($user);

もちろん選択にも使えます。

$spec = new PopularUserSpecification();
$popularUsers = array_filter(function (User $users) use ($spec): void {
    return $spec->isSatisfiedBy($user);
}, $users);

ORMでの選択

Eloquent

applyToEloquentメソッドを実装します。
このメソッドにwhereメソッド等で選択条件を記述します。

use Illuminate\Contracts\Database\Eloquent\Builder;

/**
 * {@inheritdoc}
 */
public function applyToEloquent(Builder $query): void
{
    $query->where('votes', '>', 100);
}

applyToEloquentメソッドにEloquentビルダーを渡して呼び出すことで、クエリーに選択条件を追加できます。

$query = User::query(); // UserはあなたのEloquentモデルです
$spec = new PopularUserSpecification();
$spec->applyToEloquent($query);
$popularUsers = $query->get();

Doctrine

applyToDoctrineメソッドを実装します。
このメソッドにandWhereメソッド等で選択条件を記述します。

use Doctrine\ORM\QueryBuilder;
use Ngmy\Specification\Support\DoctrineUtils;

/**
 * {@inheritdoc}
 */
public function applyToDoctrine(QueryBuilder $queryBuilder): void
{
    $queryBuilder->andWhere($queryBuilder->expr()->gt(
        DoctrineUtils::getRootAliasedColumnName($queryBuilder, 'votes'),
        DoctrineUtils::createUniqueNamedParameter($this, $queryBuilder, 100),
    ));
}

applyToDoctrineメソッドにクエリービルダーを渡して呼び出すことで、クエリーに選択条件を追加できます。

/** @var \Doctrine\ORM\EntityManager $entityManager */
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder->select('u')->from(User::class, 'u'); // UserはあなたのDoctrineエンティティーです
$spec = new PopularUserSpecification();
$spec->applyToDoctrine($queryBuilder);
$popularUsers = $queryBuilder->getQuery()->getResult();

合成

仕様をAND、OR、NOTで合成できます。
仕様を合成するとisSatisfiedByメソッドやapplyToEloquentapplyToDoctrineメソッドに記述した条件も合成されます。

AND

仕様のandメソッドに別の仕様のインスタンスを渡して呼び出すことで、2つの仕様をANDした新しい仕様を生成できます。

$spec1 = new Specification1();
$spec2 = new Specification2();
$spec3 = $spec1->and($spec2);

OR

仕様のorメソッドに別の仕様のインスタンスを渡して呼び出すことで、2つの仕様をORした新しい仕様を生成できます。

$spec1 = new Specification1();
$spec2 = new Specification2();
$spec3 = $spec1->or($spec2);

NOT

仕様のnotメソッドを呼び出すことで、自分自身をNOTした新しい仕様を生成できます。

$spec1 = new Specification1();
$spec2 = $spec1->not();

使用例

  • ngmy/php-specification-example
    • このプロジェクトはPHP Specificationを使用して仕様パターンを実装するコード例です。
      ドメイン駆動設計のアプローチに従って書かれており、仕様とリポジトリーを組み合わせるコード例があります。
      ORMにはEloquentとDoctrineを使用しています。

License

PHP SpecificationはMITライセンスの下で提供されるオープンソースソフトウェアです。