はじめに
ビルダーパターンを使うと、インスタンスの生成が分かりやすく行えるということで、愛用されている方も多いと思います。今回はC#のインスタンス生成でビルダーパターンを使う場合と使わない場合を個人的に考えてみました。
ビルダーパターンと言っても複数種類あるようなのですが、今回は下記リンクで言うところのEffective Java Builderのようなインタフェースの記述をしていきます。私はEffective Java読んだことがないんですけど。
参考:Javaで書くBuilderパターンのパターン
http://qiita.com/disc99/items/840cf9936687f97a482b
ビルダーパターンを使わない場合
使わない場合の方が多いので先に説明します。
生成方法が1種類のみ1
var imageSize = new ImageSize(height: 50, width: 60);
生成方法が1種類の場合はビルダーパターンは使用しません。
なぜかと言うと、C#では名前付き引数で渡すパラメータを把握できるからです。今回の場合、ImageSizeコンストラクタに高さと横幅を渡していることが、直感的にわかります。
- 名前付き引数を使う場合は、メソッド定義の引数名が変わると呼び出し側の名前付き引数の修正が必要になるので、注意が必要です。
今回は引数の数が少ないですが、多くなりそうならリファクタリングを行います。
書籍:リファクタリング「第10章メソッド呼び出しの単純化」あたりが参考になると思います。
生成方法が複数種類あるがどれも単純
var point1 = new Point(x: 50, y: 60);
var point2 = new Point(dw: 0x0003C0032);
上と同じく、名前付き引数で生成方法が分かるため。
ビルダーパターンを使う場合
生成方法が複数あり、複雑な生成方法を含む
// 複雑な生成方法のつもり
WebRule webRule1 = Rule.WebInfo(webConfig).And.Config(myConfig).Build();
WebRule webRule2 = Rule.LocalPolicy;
コンストラクタが複数種類あり、複雑な生成方法を含む場合は、ビルダーパターンの使用を検討したほうが良いでしょう。
例では、WebRuleクラスの生成をRuleクラスに任せることで、WebRuleのコンストラクタを書かなくていいような実装をしています。
実装者によっては下記のような実装になったりと、ここらへんは人によっていろいろな考えが出る部分だと思います。
// 複雑な生成方法のつもり
WebRule webRule1 = WebRule.Rule.WebInfo(webConfig).Config(myConfig);
WebRule webRule2 = WebRule.LocalPolicy();
-
コンストラクタが1種類の場合と考えてもらっていいです。たまに1つのコンストラクタで複数種類の生成を行おうとする人がいるので注意が必要ですが… ↩