JavaScriptオブジェクト指向パターン:ファクトリパターン
コードを整理することで、多くの苦痛から私たちを救うことができます。 オブジェクト指向プログラミングの機能を使用して、特定のデザインパターンを使用して、必要に応じて、読みやすさを向上させ、冗長性を減らし、抽象化を作成できます。 そのようなパターンの1つがファクトリパターンです。
ファクトリパターンは、DRY方法論に従うオブジェクト指向パターンの一種です。 名前が示すように、オブジェクトインスタンスは、ファクトリを使用して必要なオブジェクトを作成することによって作成されます。
ファクトリパターンを使用してalligator
オブジェクトをアセンブルする非常に簡単な例を見てみましょう。 そのためには、まずalligator
パーツを作成するファクトリを作成する必要があります。
class TailFactory { constructor(props) { this.tailLength = props.tailLength; } }; class TorsoFactory { constructor(props) { this.color = props.color; } }; class HeadFactory { constructor(props) { this.snoutLenth = props.snoutLenth; } };
ここで、実際のファクトリクラスとユーザーの間の仲介役として機能するクラスを作成します。 これをReptilePartFactory
と呼びましょう。
class ReptilePartFactory { constructor(type, props) { if(type === "tail") return new TailFactory(props); if(type === "torso") return new TorsoFactory(props); if(type === "head") return new HeadFactory(props); } };
さあ、実際のワニを組み立てて、ReptilePartFactory
を使用して必要な部品を入手しましょう。
let alligator = {}; let alligatorProps = { tailLength : 2.5, color: "green", snoutLenth: 1 }; //gets a tail from the tail factory alligator.tail = new ReptilePartFactory("tail", alligatorProps); //gets a torso from the torso factory alligator.torso = new ReptilePartFactory("torso", alligatorProps); //gets a head from the head factory alligator.head = new ReptilePartFactory("head", alligatorProps);
上記のパターンを見てください。同じReptilePartFactory
を使用して、ワニのようなオブジェクトのパーツを作成できるようです。 バックグラウンドのファクトリは、最終的なオブジェクトの性質について知る必要はありません。
したがって、ファクトリパターンを使用すると、特定の利点が得られます。
- 動的オブジェクト作成:オブジェクトのタイプが実行時に決定される場合に使用できます。
- Abstraction :ユーザーが実際のオブジェクトのコンストラクターに実際にアクセスする必要はありません。
- 再利用性/メンテナンス:同じファクトリを同様のオブジェクトに使用でき、多くのコードを変更することなく、新しいオブジェクトクラスを簡単に追加/削除できます。
ファクトリパターンについてある程度理解できたので、より良いファクトリパターンコードの記述について少し調べてみましょう。
上記の例では、if-ladderを使用して、ユーザー入力に基づいて呼び出すファクトリを見つけます。 これは単純な実装であり、直感的であり、変更に対してあまりオープンではありません。 後で追加する新しいパーツがある場合は、ReptilePartFactory
を邪魔する必要があります。 これは、「ソフトウェアエンティティ(クラス、モジュール、関数など)は拡張のために開いているが、変更のために閉じている必要がある」というSOLIDの原則に違反しています。
ファクトリクラスをオブジェクトに格納し、必要なパーツをキーとして使用して、必要なパーツファクトリを呼び出すのはどうですか? まず、工場を登録する必要があります。それは次のように簡単です。
let registeredPartFactories = {}; registeredPartFactories['tail'] = class TailFactory{ ... }; registeredPartFactories['torso'] = class TorsoFactory { ... }; registeredPartFactories['head'] = class HeadFactory { ... };
そして今、抽象化レイヤーは次のようにファクトリを呼び出すことができます。
class ReptilePartFactory { constructor(type, props) { return new registeredPartFactories[type](props); } };
このアプローチははるかにクリーンで、ReptilePartFactory
のコードに影響を与えることなくファクトリを拡張できます。
結論は
他にも、読みやすさと品質を向上させるオブジェクト指向パターンがいくつかあります。 したがって、ファクトリパターンを使用する前に、実際の要件があるかどうかを確認してください。 同様のタイプのオブジェクトを繰り返し作成し、作成ロジックにある程度の抽象化を提供しながら、これらのオブジェクトを使用して新しいインスタンスを作成するためのレイヤーが必要な場合は、はい-ファクトリパターンが適切なオプションです。