抽象ファクトリークラスは、関連するオブジェクトファミリーを生成するデザインパターンです。
このパターンは、異なる種類のオブジェクトを生成し、それらを組み合わせて使う場合に役立ちます。
カクテル製造の例を考えてみましょう。
カクテルはベース(アルコール)とソフトドリンクから構成され、異なるカクテルには異なるベースとソフトドリンクが必要です。
抽象ファクトリークラスは、カクテルごとに適切なベースとソフトドリンクを生成するファクトリーを提供します。
クライアントコードは、カクテルを指定するだけで、詳細な生成プロセスを意識せずにカクテルを作成できます。
このデザインパターンは、一貫性を保ちつつ新しいオブジェクトファミリーをサポートする際に便利です。
<?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();