Head FirstのFactoryパターンの
例え話が「ピザ屋」のお話だったので、
すんごいピザが食べたくなり、ピザホール一人で食べました。
やっぱりマルゲリータですよね。
んで、追いオリーブオイル。
Factoryパターン一族
– Simple Factory[正確にはFactoryパターンではない]
– Factory Method
– Abstract Factory
今回は最後のAbstract Factoryについてです!
Abstract Factory
オブジェクトを作成をカプセル化し、依存度を下げる。(Factory Methodと同じ)
FactoryMethodと異なり、オブジェクトコンポジションを使います。
具象クラスを指定することなく、
一連の関連オブジェクトや依存オブジェクトを作成するための
インターフェースを提供する。
→ 使い手は、抽象インターフェースを使って、
実際に作成される具体的な製品を知ることなく、
一連の製品を作成できる。
いいところ:
使い手は、具体的な製品の詳細から完全に分離されます。
→ 役割分担できて、個々のクラスの責任が小さくなる
クラス図はこんな感じ

Head Firstでは、
– 工場:ピザの食材を作る食材工場
– 製品:ピザの食材
を例としていました。
こんな感じ(PHPStormのクラス図作れるの教えてもらったので、早速)

PizzaIngredientFactoryクラスで、
関連する一連の食材(Dough, Sauce, Cheese, …)オブジェクトを
まとめてグループ化して作れるのがいいところです。
▶︎ PizzaIngredientFactory ←抽象的な食材工場
interface PizzaIngredientFactory
{
//実装クラスにピザの食材(製品)の作成方法は任す。
public function createDough(): DoughInterface;
public function createSauce(): SauceInterface;
public function createCheese(): CheeseInterface;
...
}
▶︎ NYPizzaIngredientFactory (PizzaIngredientFactoryの実装クラス)
↑具象な食材工場
class NYPizzaIngredientFactory implements PizzaIngredientFactory
{
//具体的なピザの食材(オブジェクト)を作成する。
public function createDough(): DoughInterface
{
return new ThinCrustDough();
}
public function createSauce(): SauceInterface
{
return new MarinaraSauce();
}
...
▶︎ DoughInterface ←抽象的な食材
interface DoughInterface
{
public function getName(): string;
}
▶︎ ThinCrustDough (DoughInterfaceの実装クラス)
↑具象な食材
class ThinCrustDough implements DoughInterface
{
private $name;
public function __construct()
{
$this->name = "うっすい生地";
}
public function getName(): string
{
return $this->name;
}
}
ただし、食材が追加された時、
Product(MeetInterface, Bacon)の追加だけでなく、
PizzaIngredientFactoryと
PizzaIngredientFactoryを実装する全てのクラスを変更する必要があります。
→影響範囲が大きめです。
例: 肉(食材)を追加する場合
– PizzaIngredientFactory
interface PizzaIngredientFactory
{
//実装クラスにピザの食材(製品)の作成方法は任す。
public function createDough(): DoughInterface;
public function createSauce(): SauceInterface;
public function createCheese(): CheeseInterface;
...
+ public function createMeet(): CheeseInterface;
}
– NYPizzaIngredientFactory
class NYPizzaIngredientFactory implements PizzaIngredientFactory
{
...
+ public function createMeet()
+ {
+ //MeetInterfaceの実装クラスをインスタンス化する
+ return new Bacon();
+ }
}
ある程度、固定された一連のオブジェクトがあって、
それらを作成する必要がある時に使えそうですね。
