Abstract Factory
Tweet抽象クラスを生成する抽象クラスを利用したデザインパターン。
「抽象的な工場」と訳される場合があると言われているが、言われている例をあまり見たことがない。
同じような構造のクラスを生成するパターンが複数に分岐する場合に有効。
Factory Methodパターンとの違いは正直よくわかっていないけど、Factory Methodをいっぱい作ったらAbstract Factoryなんじゃないの?ぐらいの認識。
例
釣り具
メーカのリール
とロッド
を生成するFactoryクラスがあり、
それぞれの、メーカはsimano
とDaiwa
を準備する場合。
UML
重要なところ
Abstract Factoryクラスで抽象クラスを生成するようにメソッドを定義する。
また、Abstract Factoryクラス自体も抽象クラスとして実装する。
あとは、Factoryクラスのパターン
として具象クラスを作る。
以下の例では、Daiwaファクトリクラスを作っている。
こうすることにより、Factoryクラスをパターン
で分けることができる。
今回の例では、FishingTools(釣り具)のパターンがDaiwaとsimanoが存在するため、
- Daiwaとsimanoを
具象クラス
として定義 - FishingTools(釣り具)を
抽象クラス
として定義
これによりクライアントコードは抽象クラス
へ依存させることができるようになる。
全体像
PHPで書いてみる
FishingTools(Abstract Factory)1
2
3
4
5interface FishingTools {
public function getReel() : Reel;
public function getRod() : Rod;
}
Daiwa(Concrete Factory)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17namespace FishingTools;
use Reel\Daiwa as DaiwaReel;
use Rod\Daiwa as DaiwaRod;
class Daiwa implements FishingTools
{
public function getReel() : Reel
{
return new DaiwaReel(); // 具象クラスに依存
}
public function getRod() : Rod
{
return new DaiwaRod(); // 具象クラスに依存
}
}
Client Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Fisher {
private $reel;
private $rod;
public function __construct(FishingTools $tools) // <- 抽象に依存
{
$this->reel = $tools->getReel();
$this->rod = $tools->getRod();
}
public function playFishing()
{
while($this->reel->trun()) {
// @todo: 釣れたか判定を書く
}
}
}
$fishingTools = new FishingTools\Daiwa();
$fisher = new Fisher($fishingTools);
$fisher->playFishing();
このようにClient Codeを抽象クラスに依存させることによって、
$fishingToolsはDaiwaでもsimanoでも釣り具を生成できればなんでもいい状態ができる。
この、抽象クラスに依存できるところにOOP的な旨味があるのではないかと思う。
まとめ
抽象クラス(Abstract Class)
を生成する抽象クラス(Abstract Factory)
を作る- 実際にどの
具象クラス(Concrete Class)
を生成するのかは具象クラス(Concrete Factory)
に実装する
所感
動機としては、会社でデザインパターンについてどれほど理解があるのかのアンケートがあった。
デザインパターンの復習と学習のため、アンケートででてきたデザインパターンを1日ずつPHPで書いてみようと思う。
39種類あったので6/24ぐらいには39種類全て書けるかと思う。
また、デザインパターンについては自信があまりないので
- これで伝わるのか
- そもそも認識が正しいのか
が不安