[Go言語]Factoryパターン~前編~

こんにちは、KOUKIです。

この記事では、デザインパターンの一つであるFactoryパターンについて、紹介しています。

デザインパターン

シチュエーション

Factoryパターンは、インスタンスの生成に関するデザインパターンです。

例えば、Person構造体を実装したとしましょう。

これを使うためには、次のようにインスタンス化します。

しかし、Person構造体にパラメータが増えるとどうなるでしょう。

この場合は、以下のように値を追加する必要があります。

3つだけならまだ許容できますが、このパラメータが増え続けていったらゾッとしますよね?

誤った情報を渡すことでバグになるかもしれないので、これを回避できれば最高です!

Factory Function

インスタンスの生成には、コンストラクタ関数を作成しましょう

そして、ユーザーが手動で設定する必要のないパラメータは、デフォルト値として定義すれば良さそうです。

これでコードの呼び出し側は、NewPersonを呼び出すことで、Moneyにデフォルトの値(1000)が入った状態のインスタンスをいつでも取得できるようになります。

Name/Ageが動的に変わる(ユーザーが生成したい)データを渡すことがポイントで、馬鹿正直に全てのデータを呼び出し元で用意する必要はなく、というよりむしろ、ユーザーがインスタンスの詳細を把握していなくてもName/Ageを渡すということだけ知っていれば、このPerson構造体を使えるぜ!ということなんです。

つまり、インスタンス生成が簡単になるわけですね。今回は、例が簡単すぎてその威力を計りかねると思いますが、このような考え方は、シンプルなプログラムを実装する上で、重要だったりします。

Factory Interface

先ほどのコードには、2つのいけていない点があります。

1つは、Person構造体がPublicで定義されているので、外部から値を自由に変更できることです。

パラメータが呼び出し元で自由に変更できると、予期しないバグが発生することがあるので、あまり変更されたくありません。

もう一つは、作成できるインスタンスの種類がたったの一つだということです。何故なら、NewPersonの戻り値がPerson構造体になっているためです。

例えば、新たにRichPerson/PoorPersonを生成したい場合は、コンストラクタを追加する必要があります。

これを解決するために、Interfaceを活用しましょう!

まず、先ほどのサンプルコードをInterfaceを使ったものに書き換えます。

復習ですが、Go言語のPublic/Privateの宣言は、先頭の文字列が大文字か小文字かで区別されます。

ここまでで、呼び出し元でパラメータを自由に変更できる問題を解決したことになります。

また、Interfaceに宣言したSayMySelfを紐付けたい構造体のメソッドとして定義すれば、Interfaceを実装したことになります。

コンストラクタの戻り値をPerson Interfaceにしていますが、この紐付けが完了したので、person構造体を返すことができます。

こうすることで、以下のようなことが行えます。

新しくrichPerson/poorPerson構造体を定義し、Interfaceと紐づけるため、それぞれにSayMySelfをメソッドとして実装しました。

そして、NewPerson コンストラクタで、条件によって返却される構造体を変更する処理を追加しています。

この実装パターンは、DBの切り替え処理(MySQL -> PostgreSQLみたいな)などで利用できるので大変便利です。

次回

次回は、Factoryパターンの後編になります。

Go言語まとめ

ソースコード

Factory Function

Factory Interface

コメントを残す