- Builderパターンを勉強したけどイマイチわからない
- Builderパターンのメリットをわかりやすく知りたい
本記事はこのようなお悩みを解決します。
デザインパターンを勉強することは大切ですが、いまいち理解しきれないこともありますよね。
結局メリットが何かもわからず、丸覚えしてしまいがちです。
でも、そのままでは何も身につかない無駄な勉強になってしまいます。
そこで、この記事は「初心者がBuilderパターンを理解できる」をモットーに分かりやすく紹介したいと思います。
よく見かけるBuilderパターンの基礎となるような内容ですので、ぜひ最後まで読んでみてくだだい。
Builderパターンのメリット
Builderパターンは、口語的に言うと「クラスのフィールドが多いからコンストラクタが分かりづらくてやべぇ」なときに使うと嬉しいパターンです。
「クラスのフィールドが多いからコンストラクタが分かりづらくてやべぇ」の状態がどのように解消されるか、1つずつ見ていきましょう。
1. thisコンストラクタを連発する状態(良くない)
フィールドが多いなら、フィールドの数に合わせた全てのコンストラクタを作ろう、というのがこの考え方です。
/** * コンストラクタがややこしすぎる例 * / class MatchingAppInfo { private String name; // 必須 private int sex; // 必須 private int age; private int income; private String address; public MatchingAppInfo(String name, int sex) { this(name, sex, 0); } public MatchingAppInfo(String name, int sex, int age) { this(name, sex, age, 0); } public MatchingAppInfo(String name, int sex, int age, int income) { this(name, sex, age, income, "秘密"); } public MatchingAppInfo(String name, int sex, int age, int income, String address) { this.name = name; this.sex = sex; this.age = age; this.income = income; this.address = address; } }
しかし、thisの連発で読みにくくて萎えますね、、しかも「0」ってなんの数字だよ、となってしまう危険性もあり、とても分かりにくいです。
ココがダメ
- コンストラクタが多くて読みにくい
- 0やfalseといった意味が分からないものが生まれがち
2. settterパターン(まだ微妙)
続いて、thisの連発を避けようとして「必要なものだけ入れていけばいいじゃん」の考えからsetterパターンが生まれました。
/** * setterでセットしていく例 * / class MatchingAppInfo { private String name = ""; // 必須 private int sex = ""; // 必須 private int age = 0; private int income = 0; private String address = ""; public void setName(String name) { this.name = name; } public void setName(int sex) { this.sex = sex; } public void setName(int age) { this.age = age; } public void setName(int income) { this.income = income; } public void setName(String address) { this.address = address; } }
よく見る形ですし、だいぶ良くなりましたね。
ただし、このパターンは「生成処理が大変」というデメリットを抱えています。
下のコードのように、いざこのクラスを使おうと思うと生成処理が1行で終わらなくなってしまうんですよね。
MatchingAppInfo info = new MatchingAppInfo(); info.setName("田中"); info.setSex(1); info.setAge(25); info.setIncome(350); info.setAddress("東京"); // 6行も使ってる!!!
ココがダメ
生成を完了するまでのコードが長い
3. Builderパターン
最後にBuilderパターンを紹介します。
Builderパターンを使うことで、1,2のデメリットを解消し、とても読みやすいコードを書くことができるようになります。
/** * Builderパターン */ class MatchingAppInfo { private final String name; // 必須 private final int sex; // 必須 private final int age; private final int income; private final String address; // privateコンストラクタ(Builderからしか呼べない) private MatchingAppInfo(Builder builder) { name = builder.name; sex = builder.sex; age = builder.age; income = builder.income; address = builder.address; public static class Builder { private String name; // 必須 private int sex; // 必須 private int age = 0; private int income = 0; private String address = ""; // Builderのコンストラクタ。必須項目をセット public Builder(String name, int sex) { this.name = name; this.sex = sex; } // オプションをセットするメソッド public Builder Age(int val) { this.age = val; return this; } public Builder Income(int val) { this.income = val; return this; } public Builder Address(String val) { this.address = val; return this; } // MatchingAppInfoを生成 public MatchingAppInfo build() { return new MatchingAppInfo(this) } } } }
ちょっと長くなって読みにくいかもしれませんが、実際にMainで使うと、以下のような綺麗なコードになります。
MatchingAppInfo info = MatchingAppInfo.Builder("田中", 1) .Age(25).Income(350).Address(東京).build(); MatchingAppInfo info2 = MatchingAppInfo.Builder("木村", 2) .Address(東京).build();
スッキリしていて、何をやっているのか明確ですよね。
任意のパラメータをセットするのも、setterパターンに比べてだいぶ落ち着いています。
このように、フィールドやコンストラクタが多いクラスに対しては、Builderという生成に関するクラスを中に入れてしまうことで読みやすいコードを作ることができます。
ココがポイント
- Builderクラスに生成ロジックを分離できる。
- 呼び出す側のコードが読みやすい。
まとめ
Builderパターンの基礎についてご紹介しました。
Builderパターンを使うと、フィールドやコンストラクタが多いクラスの可読性をあげることができます。
なお、デザインパターンや綺麗なJavaコードを書くには以下の本を使って勉強することがおすすめなので、「良いコードが書きたい!」という方はぜひ勉強してみてください。
最後までお読みいただきありがとうございました。