デザインパターンとは、システム設計におけるクラスやインターフェースの関係に名前をつけたものです。 GoFの23のパターンが有名です。デザインパターンというのは、どんなパターンなのか、パターンの目的は何かということを覚えることが非常に重要なのですが、これを実際に適用しようとした場合に、いつ適用していいかが見えてこないとお話になりません。

そこで、自分の勉強も兼ねつつ、パターンの実践時における使用場所や、パターンを適用するきっかけを見つけられるようにメモしておきます。

10回目になりました。インスタンスの生成手順や生成内容が複雑な場合に、インスタンス生成作業を軽減するBuilderパターンのメモです。

Builderパターン

Builderパターンは、インスタンス生成手順が複雑な場合やインスタンス生成構成が複雑な場合に、生成を簡略化するパターンです。

インスタンス生成手順が複雑な場合というのは、例えば次のような場合です。

  • インスタンスの生成が他のオブジェクトとの関連で成り立っている
  • 外部リソースを読み取る処理によって作られるインスタンス
  • データベースからデータを読み取り、加工しながら作成されるインスタンス

Template Methodパターンで取り扱った、インスタンス生成手順を規則正しく決めたい場合なども、Builderパターンは応用できます。

手順に関して言うと、Template MethodパターンとBuilderパターンの違いは、インスタンス生成の役割を誰が負うのかというところです。Template Methodパターンは、インスタンス生成の手順をスーパークラス(親クラス)で決めます。一方Builderパターンは、生成の手順はDirectorクラス(他のクラス)が責任を負います。

Builderパターンで一番のポイントは、誰がインスタンスの生成手順を知っているのかというところです。Directorクラスが知っているというのがその答えです。

もうひとつのポイントは、Directorを使うユーザは、Builderで作られたインスタンスが何かということを知っていなければならないという点でしょう。どういうことかというと、まずクラス図を見てください。

「User」クラスが「Director」クラスを呼び出して作成した「Product」を使用する点に注目です。「User」クラスは「Director」がどんな「Product」を生成するのかを知っていなければ使いようがないという点を表しています。

実装の点から見ると、DirectorをBuilder毎に作り成果物の取得で固有のProductを返すようにするか、成果物を抽象化しておき、取得時にキャストして使うかということです。

パターンの適用タイミング

Builderパターンの長所は、UserがProductの生成手順をすべてDirectorに任せているという部分です。これによって、Productの生成手順が変わったり、どんなに複雑な処理をしていても、Userからしてみれば、変更する必要がないのです。

設計時の注意点ですが、Builderが提供する生成手順は、増やしたり減らしたりするのが困難であるということを覚えて置いてください。オブジェクト指向の原則である開放・閉鎖原則では、拡張には開いていて(Open)、修正には閉じている(Closed)必要があります。ConcreteBuilderの拡張は、容易にできますが、親クラスのBuilderの機能を増やすことは、子クラス全体に修正が及ぶ可能性があります。

これを回避するためには、十分な設計と変更に強い構造をBuilderに持たせることです。

Builderパターンのまとめです。インスタンス生成に手順がある場合外部リソースを使ってインスタンスを作成しなければいけない場合コンストラクタで引数の違うものがたくさんできてしまった場合

実装サンプルと参考文献

Builderパターンの実装方法をもっと詳しく知りたい場合は、下記のサイトにアクセスするのをお勧めします。もしくは、参考書籍を載せておきますので、そちらをお買い求めください。(^^;


  • 独習シリーズのデザインパターン編。デザインパターンを一人でも学べます。

  • Sun Microsystemのお墨付き。GoF以外のパターンも学べます。

  • UMLを使って、オブジェクト指向のいいとこ取りができます。

  • デザインパターンだけではなく、ソフトウェア設計の原則やプラクティスまで学びたい人におすすめ