Builder パターン
複雑なオブジェクトの生成をメソッドチェーンで段階的に構築するデザインパターン
設計パターンビルド
Builder パターンとは
Builder パターンは、コンストラクタの引数が多いオブジェクトや、生成手順が複雑なオブジェクトを、メソッドチェーンで段階的に構築する GoF デザインパターンである。引数の順序を間違えるリスクを排除し、オプショナルなパラメータを柔軟に設定できる。
問題: 引数が多いコンストラクタ
// ❌ 引数が多い: どれが何か分からない、順序を間違えやすい
const config = new ServerConfig(3000, 'localhost', true, false, 30000, 100, '/api', true);
Builder で解決
class ServerConfig {
readonly port: number;
readonly host: string;
readonly cors: boolean;
readonly logging: boolean;
readonly timeout: number;
readonly maxConnections: number;
private constructor(builder: ServerConfigBuilder) {
this.port = builder.port;
this.host = builder.host;
this.cors = builder.cors;
this.logging = builder.logging;
this.timeout = builder.timeout;
this.maxConnections = builder.maxConnections;
}
static builder() { return new ServerConfigBuilder(); }
}
class ServerConfigBuilder {
port = 3000;
host = 'localhost';
cors = false;
logging = true;
timeout = 30000;
maxConnections = 100;
setPort(port: number) { this.port = port; return this; }
setHost(host: string) { this.host = host; return this; }
enableCors() { this.cors = true; return this; }
disableLogging() { this.logging = false; return this; }
setTimeout(ms: number) { this.timeout = ms; return this; }
setMaxConnections(n: number) { this.maxConnections = n; return this; }
build() { return new ServerConfig(this); }
}
// ✅ メソッドチェーン: 何を設定しているか明確
const config = ServerConfig.builder()
.setPort(8080)
.enableCors()
.setTimeout(60000)
.build();
TypeScript では Builder が不要なケースが多い
TypeScript ではオブジェクトリテラル + デフォルト値で Builder と同等のことが実現できる。
// TypeScript: オブジェクトリテラルで十分
interface ServerConfig {
port?: number;
host?: string;
cors?: boolean;
timeout?: number;
}
function createServer(config: ServerConfig = {}) {
const { port = 3000, host = 'localhost', cors = false, timeout = 30000 } = config;
// ...
}
createServer({ port: 8080, cors: true });
Java や C# では Builder パターンが頻繁に使われるが、TypeScript ではオブジェクトリテラルの方がシンプルだ。
Builder が有効なケース
- 生成過程にバリデーションが必要 (
build()時に必須フィールドをチェック) - 不変オブジェクトを段階的に構築する
- 流暢なインターフェース (Fluent Interface) を提供したい
AWS SDK の Builder パターン
AWS SDK v3 の Command オブジェクトは Builder 的なパターンを使っている。
const command = new PutCommand({
TableName: 'Orders',
Item: { orderId: '123', status: 'pending' },
ConditionExpression: 'attribute_not_exists(orderId)',
});
ビルダー vs コンストラクタ
| 観点 | コンストラクタ | ビルダー |
|---|---|---|
| 引数が少ない | ✅ シンプル | ❌ 過剰 |
| 引数が多い | ❌ 読みにくい | ✅ 読みやすい |
| オプション引数 | △ | ✅ |
| バリデーション | コンストラクタ内 | build() 時 |
理論と実装の両面から学ぶなら関連書籍が参考になる。