yynsmk's tech blog

何でもできる=何にもできない

BuilderパターンとFactory Method・Template Methodパターンの違いは?

Java言語で学ぶデザインパターン入門を読んでいて疑問に思う点があったが、いろいろググって多分理解したのでメモ。

今回の題材は、第7章で学ぶBuilderパターン。
解説するのは、タイトルにもある以下の2つの疑問について。

  1. Factory Methodパターンとどう違うのか?
  2. Template Methodを使えばいいのではないか?

Builderパターンとは?

複雑な構造を持ったインスタンスの作成を簡単にしてくれるパターン。
インスタンスを組み上げていく過程をブラックボックス化できる。
Builder役、ConcreteBuilder役、Director役、Client役があり、Builderでインスタンスの各部分を作るためのメソッドを定義し、Directorがそれらのメソッドを使ってインスタンスを作成する。

※Builderパターンの細かい説明等は書籍や参考サイトを参照してください。
<参考サイト>
7. Builder パターン | TECHSCORE(テックスコア)
Javaで書くBuilderパターンのパターン - Qiita
Builderパターン - Qiita
Tech Tips: デザインパターン(7) Builder

Factory Methodパターンとどう違うのか?

一つ目の疑問。 Factory MethodパターンもBuilderパターンもどちらもインスタンス作成のためのパターンであるが、具体的にどう違っていて、どう使い分ければいいのだろうか?

Factory MethodパターンとBuilderパターンの違いを理解するポイントは、

インスタンス作成時のどの処理を共通化しているか

であるように思う。
それぞれのパターンで例を出しつつ見ていこう。

Factory Methodパターンにおける共通化

Factory Methodパターンは、全くタイプの異なるオブジェクトの作成処理を共通化してフレームワークとして提供する。
例として、本とカードを製造している一つの工場を考える。
この工場では本とカードは以下の手順を踏んで出荷される。

  1. 本・カードを作成する
  2. 完成した本とカードを商品登録する
  3. 出荷する

ここで重要なのが、本・カード自体の作成過程は当然異なるが、ステップ1〜ステップ3の流れは共通しているということ。
そのため、ステップ1〜ステップ3のプロセスをインスタンス作成のためのフレームワークとして提供できる。

Builderパターンにおける共通化

Builderパターンは、似たオブジェクトの作成過程を共通化して、手順をきれいにまとめる。

例えば、ベンツとBMWの車を作る工場を考える。
Factory Methodパターンの例と違って、この場合は両者とも車なので製造過程は同じで、材料やデザインが異なるだけである。

つまり、Builderパターンは、Factory Methodパターンに比べてミクロな視点で共通化しており、インスタンスそのものの作成過程をまとめるためのものである。

Template Methodを使えばいいのではないか?

二つ目の疑問。
Builderパターンは以下のようなクラス図(Wikipediaより引用)であるが、なぜわざわざDirectorを用意する必要があるだろうか?
construct()はTemplate MethodとしてBuilderの中に記述すればいいのではないか?

f:id:b_murabito:20190605024136p:plain

これの明確な答えはよく分からないが、「継承か委譲か問題」と関係が深いように思う。
Template Methodだとインスタンス生成はスーパークラスが担い(継承)、BuilderパターンだとDirectorが担う(委譲)。
どちらでも良さそうだが、委譲の方がクラス同士が疎結合で抽象度が高く良いらしいし、GoFのデザインパターンでも継承よりも委譲が推奨されている。
なので、とりあえずBuilderパターンは委譲を使うものなんだと覚えておこう。

<参考サイト>
Template Methodパターン
Differences between builder pattern and template method (builder vs template) - Stack Overflow