Factory Methodパターンとはどういうものか
Factoryとは工場という意味です。
Factory Method パターンは、他のクラスのコンストラクタをサブクラスで上書き可能な自分のメソッドに置き換えることで、 アプリケーションに特化したオブジェクトの生成をサブクラスに追い出し、クラスの再利用性を高めることを目的とする。(wikipediaより)
ポイントを要約すると、親クラスであるファクトリが、実際のオブジェクトの生成をサブクラスに委譲するということです。
登場するクラス
・抽象クラス
Productクラス:生成物の抽象クラス
Creatorクラス:Factoryクラス
・具象クラス
ConcreteProductクラス:生成物の具象クラス
ConcreteCreatorクラス:オブジェクト生成の具体的の実装が記述されたサブクラス
[参考]
https://ja.wikipedia.org/wiki/Factory_Method_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3
https://qiita.com/shoheiyokoyama/items/d752834a6a2e208b90ca
https://www.techscore.com/tech/DesignPattern/FactoryMethod.html/
https://think-on-object.blogspot.com/2011/11/factoryfactory-methodabstract-factory.html
Factory Methodパターンを用いるメリット/デメリット
・メリット
個々のインスタンス生成の実処理をサブクラス内で行うため、生成処理全体を小分けにし、簡潔な状態にすることができる。
・デメリット
インスタンスを変更する場合、Factoryクラスを変更する必要がある
サンプルコード
仕様
・AppleかAndroidかを判断する
生成物の抽象クラス(Product)
このクラスでは生成物のインターフェースを記述します。
abstract class Maker
{
protected $name = "";
protected $brouser = "";
public function getName()
{
return $this->name;
}
public function getBrouser()
{
return $this->brouser;
}
public function getInformation()
{
return "Maker:" . $this->getName() . "\n" . "BrouserName:" . $this->getBrouser() . "\n";
}
}
Factoryクラス(Creator)
このクラスでオブジェクトを生成する流れを実装します。
今回は抽象メソッドにしていますが、createSmartphoneメソッドにデフォルトの処理を入れても良いです。
abstract class SmartphoneFactory
{
public function create()
{
$smartphone = $this->createSmartphone();
return $smartphone;
}
abstract protected function createSmartphone(); // デフォルト処理を設定したい場合はここに入れればよい
}
生成物の具象クラス(ConcreteProduct)
実際に生成するオブジェクトの設定を行います。
class Apple extends Maker
{
protected $name = "Apple";
protected $brouser = "Safari";
}
class Google extends Maker
{
protected $name = "Android";
protected $brouser = "GoogleChrome";
}
Factory Methodを含むサブクラス(ConcreteCreator)
このクラスで先のFactoryクラスのcreateSmartphoneメソッドをオーバーライドし、それぞれで異なるインスタンスを生成している。
この場合それぞれオーバーライドしたcreateSmartphoneメソッドがFactory Methodである。
class AppleSmartphoneFactory extends SmartphoneFactory
{
// Factory Method
protected function createSmartphone()
{
return new Apple();
}
}
class AndroidSmartphoneFactory extends SmartphoneFactory
{
// Factory Method
protected function createSmartphone()
{
return new Google();
}
}
使ってみる
$appleSmartPhoneFactory = new AppleSmartphoneFactory();
$appleSmartPhone = $appleSmartPhoneFactory->create();
$androidSmartphoneFactory = new AndroidSmartphoneFactory();
$androidSmartphone = $androidSmartphoneFactory->create();
echo $appleSmartPhone->getInformation();
echo $androidSmartphone->getInformation();
/*結果
Maker:Apple
BrouserName:Safari
Maker:Android
BrouserName:GoogleChrome
*/
まとめ
・Factory Methodパターンは、異なるインスタンスを作成する機構を使用したい場合、専用のサブクラスを用意することでオブジェクトの生成部分のみ変更する形となっている。
・オブジェクトの生成自体を動的に処理する形(Factoryパターン)が多く使用される印象であるが、ここでは一旦Factory Methodなのでメソッドのみに注目しました。