
Builder(ビルダー)パターンは、「複雑なオブジェクトをステップごとに作る」ためのデザインパターンです。
Factoryとは目的が似ていますが、より構築手順を細かく制御できるのがポイントです。
概念例
ハンバーガーを作るとき、
パン → 肉 → 野菜 → ソース
の順で組み立てる。
Builderパターンは、その「手順」をオブジェクト化して再利用できるようにする。
サンプルコード
Javascriptによるサンプルコード。
Product(完成品)
class Burger {
constructor() {
this.parts = [];
}
addPart(part) {
this.parts.push(part);
}
show() {
console.log("バーガーの構成:", this.parts.join(", "));
}
}
Builder(作り方を定義するクラス)
class BurgerBuilder {
constructor() {
this.burger = new Burger();
}
addBun() {
this.burger.addPart("バンズ");
return this;
}
addPatty() {
this.burger.addPart("パティ");
return this;
}
addLettuce() {
this.burger.addPart("レタス");
return this;
}
addSauce() {
this.burger.addPart("ソース");
return this;
}
build() {
return this.burger;
}
}
Director(組み立ての手順をまとめる:任意)
class BurgerDirector {
constructor(builder) {
this.builder = builder;
}
makeCheeseBurger() {
return this.builder.addBun().addPatty().addLettuce().addSauce().build();
}
makeSimpleBurger() {
return this.builder.addBun().addPatty().build();
}
}
利用側
const builder = new BurgerBuilder();
const director = new BurgerDirector(builder);
const burger1 = director.makeCheeseBurger();
burger1.show(); // → バーガーの構成: バンズ, パティ, レタス, ソース
const burger2 = director.makeSimpleBurger();
burger2.show(); // → バーガーの構成: バンズ, パティ
ポイント解説
サンプルコードの登場人物(見出し用語)は以下の認識で考えてください。
Builder:作り方を知っている人
Director:どんな順で作るかを決める人
Product:最終的にできあがるもの
手順を変えるだけで、違う種類のオブジェクトを簡単に作れる。
インスタンス化したプロダクトクラスは同じ手順で実行され、それを順番に実行していくのが、Directorの役割。
利用者(Product)は、ただ、Directorクラスを実行するだけでいいので、それぞれの工程内での依存が行われ、手順が確定的に実行されるという安定感が得られます。
メリット
・生成過程を分離できる(構築の自由度が高い)
・同じ作り方で、異なる構成のオブジェクトを簡単に作れる
・「流れるようなメソッドチェーン」で書けて可読性が高い
デメリット
・クラスが多くなる
・シンプルなオブジェクトには過剰
よく使われる場面
・複雑な設定オブジェクトの構築(例:クエリ、UI設定、HTTPリクエストなど)
・長いコンストラクタ引数を避けたい場合
・JSONやHTMLのような階層的データ生成
おまけ : 関数型で書くパターン
function createBurger(options = {}) {
return {
bun: options.bun || "普通のバンズ",
patty: options.patty || "ビーフ",
sauce: options.sauce || "ケチャップ",
lettuce: options.lettuce || false,
show() {
console.log(this);
},
};
}
const burger = createBurger({ bun: "ごまバンズ", lettuce: true });
burger.show();
あとがき
手順が確定的なデータのモデル構築の場合に使うのが良さそうです。
個人的には、工程手順の、インスタンスからのメソッド順番羅列が、もっと工程管理できる書き方にしたほうがいいような気がしますが、あくまでサンプルは、内容が理解できればいいというレベルでご覧ください。
あと、ProductクラスとBuilderクラスは、くっつけてしまってもいいような気がしますが、分ける必要があるんだろうか?という疑問もありつつ、関数型の方がすっきりしていいな・・・と思っちゃいました。
ちなみに、ファクトリーとビルダーは似ていますが、使い分けとしては、次のように考えるといいですね。
パターン化された生成 → Factory
手順が多段階・可変 → Builder
とりあえず、Builderデザインパターンは完全に理解できました。
0 件のコメント:
コメントを投稿