抽象ファクトリークラス

 抽象ファクトリークラスは、関連するオブジェクトファミリーを生成するデザインパターンです。
このパターンは、異なる種類のオブジェクトを生成し、それらを組み合わせて使う場合に役立ちます。

 カクテル製造の例を考えてみましょう。
カクテルはベース(アルコール)とソフトドリンクから構成され、異なるカクテルには異なるベースとソフトドリンクが必要です。
抽象ファクトリークラスは、カクテルごとに適切なベースとソフトドリンクを生成するファクトリーを提供します。
クライアントコードは、カクテルを指定するだけで、詳細な生成プロセスを意識せずにカクテルを作成できます。

 このデザインパターンは、一貫性を保ちつつ新しいオブジェクトファミリーをサポートする際に便利です。

<?php

/**
 * ベース(アルコール)インターフェース
 */
interface Base
{
    public function getName(): string;
}
                    
<?php

/**
 * ソフトドリンクインターフェース
 */
interface SoftDrink
{
    public function getName(): string;
}
                    
<?php

/**
 * カクテルファクトリー抽象クラス
 */
abstract class CocktailFactory
{
    abstract public function getName(): string;

    abstract public function createBase(): Base;

    abstract public function createSoftDrink(): SoftDrink;

    public function createCocktail(): void
    {
        $base = $this->createBase();
        $softDrink = $this->createSoftDrink();
        echo "Creating a {$this->getName()} with {$base->getName()} and {$softDrink->getName()}\n";
    }
}
                    
<?php

/**
 * マティーニファクトリー
 */
class MartiniFactory extends CocktailFactory
{
    public function getName(): string
    {
        return 'マティーニ';
    }

    public function createBase(): Base
    {
        return new Gin();
    }

    public function createSoftDrink(): SoftDrink
    {
        return new Vermouth();
    }
}
                    
<?php

/**
 * ジントニックファクトリー
 */
class GinTonicFactory extends CocktailFactory
{
    public function getName(): string
    {
        return 'ジントニック';
    }

    public function createBase(): Base
    {
        return new Gin();
    }

    public function createSoftDrink(): SoftDrink
    {
        return new TonicWater();
    }
}
                    
<?php

/**
 * 具体的なベースクラス
 */
class Gin implements Base
{
    public function getName(): string
    {
        return "Gin";
    }
}
                    
<?php

/**
 * 具体的なソフトドリンククラス
 */
class Vermouth implements SoftDrink
{
    public function getName(): string
    {
        return "Vermouth";
    }
}
                    
<?php

/**
 * 具体的なソフトドリンククラス
 */
class TonicWater implements SoftDrink
{
    public function getName(): string
    {
        return "Tonic Water";
    }
}
                    
<?php

// ファクトリーのインスタンスを作成し、カクテルを作成
$martiniFactory = new MartiniFactory();
$martiniFactory->createCocktail();

$ginTonicFactory = new GinTonicFactory();
$ginTonicFactory->createCocktail();