【Builderパターン】コンストラクタの初期化(new)引数が多い場合にオススメなデザインパターン

 前書き:Builderパターンとは

Builderパターンは、GoF(Gang of Four)デザインパターンの一つであり、複雑な構造を持つインスタンス生成を容易にするための手法です。

ここでの複雑な構造とは、コンストラクタの初期化引数が多いケース(例:必須の引数2個、オプション引数5個)を考えてください。何も考えずに実装すると、「引数2個+オプション引数1個の場合のコンストラクタ」を作って、「必須引数2個+オプション引数2個の場合のコンストラクタ」を作って……と、延々と頭の悪いを実装をするハメになります。

また、コンストラクタを使用する際に、引数の順番を間違える等のコーディングミスをしてしまう可能性があります。

     

このようなコンストラクタの初期化引数が多いケースには、Builderパターンを適用します。Builderパターンは、リファクタリングにおける「メソッドの引き上げ(共通化している部分を別クラスに集約する)」に近く、

  • InterfaceをもつBuilderクラス
  • BuilderクラスのInterfaceを実装するConcreateBuilderクラス
  • BuilderクラスのInterfaceでインスタンスを操作するDirectorクラス

が登場します。

必須パラメータに対してのみ設定を行うBuilderコンストラクタを呼び出し、ConcreateBuiderでオプションパラメータへの設定を行うイメージです。文字だけでは分かりづらいと思うので、本記事ではクラス図、シーケンス図、実装の順で紹介します。

                    

Builderパターン:クラス図

Builderパターンにおいて、正式にはClientクラスは登場しません。

BuilderクラスのInterfaceであるbuild_XXX相当のメソッド数は、当然クラスの設計に合わせて増加・減少します。名称も、このクラス図に合わせる必要はありません。

Interfaceを実装しているConcreteBuilderは結果を返すメソッド(get_result)を持っており、返す内容は自由です。自身(self/this)、数値、文字列でも何でも良いです。

                               

Builderパターン:シーケンス図

                     

Builderパターン:Rubyによる実装例

Rubyはinterfaceが無いので、雰囲気を伝えるための実装となります。(本当はJavaで実装するのが適切ですが、Javaをササッと書けないのでRubyにしました)

以下の実装例では、オプション引数(パラメータ)として、copyright、msgを用意しました。

ConcreteBuiderクラス相当として「HTMLを生成するHtmlBuilderクラス」「Bashスクリプトを生成するBashBuilderクラス」の二つを用意しています。HtmlBuilderクラスはcopyrightを操作し、BashBuilderクラスはmsgを操作します。

Builder相当の実装

                                                    

ConcreteBuilder相当の実装

以下の実装では、オプション引数に対してbuild()メソッドで操作しています。より多くのオプションパラメータを操作する場合は、パラメータの数だけsetterメソッドを用意した方が便利です。

                                          

Director相当の実装

                                                     

Client相当の実装

                        

Builderパターン:実装例の実行結果

                        

参考書籍:Effective Javaとデザインパターン入門

Effective Javaで、「多くのコンストラクタパラメータに直面したときはビルダーを検討する」という章があり、その章だけでは私は不完全燃焼でした。なので、積読だったデザインパターン入門でBuilderパターンへの知識を補強させていただきました。

Rubyにもデザインパターン本(下記)がありますが、未読です。本記事の実装中に感じましたが、RubyはInterfaceやsetterが無いので、Javaベースのデザインパターン実装を参考にすると、手が少し止まります。

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です