factory-pattern について
`new` を使わずにオブジェクトを生成するファクトリー関数を解説する JavaScript のデザインパターンです。複数のオブジェクトや設定可能なオブジェクトを作る開発者向けに、オブジェクトリテラルやクラスコンストラクターが適する場合も説明します。
主な機能
- 01`new` を使わないオブジェクト生成
- 02共通プロパティを持つオブジェクトの作成
- 03設定に応じたオブジェクトのカスタマイズ
- 04ファクトリーとコンストラクターの使い分け
活用シーン
- 01fullName メソッドを持つユーザーオブジェクトの作成
- 02環境設定に応じたオブジェクトの構築
- 03配列の要素をオブジェクトのプロパティへ変換
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ patternsdev/ skills --skill factory-patternインストール後、Claude Code で/factory-patternを入力して読み込まれたか確認します。
詳細
ファクトリーパターン
ファクトリーパターンでは、ファクトリー関数を使って新しいオブジェクトを作成できます。new キーワードを使わずに新しいオブジェクトを返す関数を、ファクトリー関数と呼びます。
アプリケーションで多くのユーザーが必要だとします。firstName、lastName、email プロパティを持つ新しいユーザーを作成できます。ファクトリー関数は、新しく作成したオブジェクトに fullName プロパティも追加します。このプロパティは firstName と lastName を返します。
使用する場面
- 同じプロパティを持つ複数のオブジェクトを作成する必要がある場合に使用します
- オブジェクトの作成が特定の環境や設定に依存する場合に役立ちます
使用しない場面
- 単純なオブジェクトで、プレーンなオブジェクトリテラルで十分な場合。ファクトリーを使うと不要な間接処理が増えます
- プロジェクトでクラスコンストラクターが標準的な慣例になっており、チームが
newの使用を想定している場合 - オブジェクトの作成に影響する条件分岐や設定がない場合
手順
- 現在の環境やユーザー固有の設定に基づいてカスタムオブジェクトを返すには、ファクトリー関数を使用します
- ファクトリー関数の定義を簡潔にするため、ES6 のアロー関数を優先します
- メモリ効率が重要な場合は、代わりにクラスコンストラクターの使用を検討します。インスタンス間でプロトタイプメソッドを共有できるためです
詳細
const createUser = ({ firstName, lastName, email }) => ({
firstName,
lastName,
email,
fullName() {
return `${this.firstName} ${this.lastName}`;
},
});
完璧です!これで createUser 関数を呼び出すだけで、複数のユーザーを簡単に作成できます。
比較的複雑で、設定可能なオブジェクトを作成する場合、ファクトリーパターンが役立ちます。キーと値が特定の環境や設定に依存することがあります。ファクトリーパターンを使えば、カスタムのキーと値を含む新しいオブジェクトを簡単に作成できます。
const createObjectFromArray = ([key, value]) => ({
[key]: value,
});
createObjectFromArray(["name", "John"]); // { name: "John" }
メリット
ファクトリーパターンは、同じプロパティを持つ複数の小さなオブジェクトを作成する必要がある場合に役立ちます。ファクトリー関数は、現在の環境やユーザー固有の設定に応じて、カスタムオブジェクトを簡単に返せます。
デメリット
JavaScript におけるファクトリーパターンは、new キーワードを使わずにオブジェクトを返す関数と大差ありません。ES6 のアロー関数を使えば、呼び出すたびにオブジェクトを暗黙的に返す、小さなファクトリー関数を作成できます。
ただし、多くの場合、毎回新しいオブジェクトを作成するよりも、新しいインスタンスを作成するほうがメモリ効率に優れています。
class User {
constructor(firstName, lastName, email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
const user1 = new User({
firstName: "John",
lastName: "Doe",
email: "[email protected]",
});
const user2 = new User({
firstName: "Jane",
lastName: "Doe",
email: "[email protected]",
});
ソース
参考資料
- JavaScript Factory Functions with ES6+ - Eric Elliott