やる気
- ソフトウェアシステムでは、オブジェクトの作成というタスクに直面することがよくあります。要件の変更により、作成する必要のある特定のタイプのオブジェクトが変更されることがよくあります。
- この変化にどう対処するか?従来のオブジェクト作成方法(新規)をバイパスし、「カプセル化メカニズム」を提供して、クライアントプログラムとこの「具体的なオブジェクト作成作業」の間の密結合を回避する方法
パターン定義
オブジェクトを作成するためのインターフェースを定義し、インスタンス化するクラスをサブクラスに決定させます。ファクトリメソッドは、サブクラスへのクラス(目的:デカップリング、手段:仮想関数)のインスタンス化を遅らせます。-「デザインモード」GoF
パターンの例
ファイル分割の例は以前のオブザーバーモードで説明しましたが、ここではファイル分割の例を使用して説明します。ファイルディバイダーには、複数のバイナリファイルディバイダーがあり、テキストファイルディバイダー、イメージファイルディバイダー、ビデオファイルディバイダーなどがある場合もあります。ニーズが異なる場合は、特定のタイプを作成する必要があります。
クラスISplitter { public : virtual void split()= 0 ; 仮想〜ISplitter(){} }。 クラス BinarySplitter:public ISplitter { }; クラス TxtSplitter:public ISplitter { }; クラス PictureSplitter:public ISplitter { }; クラス VideoSplitter:public ISplitter { }; クラス MainForm:public Form { TextBox * txtFilePath; テキストボックス* txtFileNumber; ProgressBar * progressBar; public : void Button1_Click() { ISplitter * Splitter = new BinarySplitter(); // 依存赖具体类 splitter-> split(); } };
しかし、設計がこのように変更されると、コードは常に変更される必要があり、スプリッターは特定の実装クラスに依存します。
ファクトリモードを使用すると、この問題を解決できます。オブジェクトを作成するためのインターフェースを定義し、インスタンス化するクラスをサブクラスに決定させます。ファクトリメソッドは、クラスのサブクラスへのインスタンス化を遅らせます。
// 抽象类 class ISplitter { public : virtual void split()= 0 ; 仮想〜ISplitter(){} }。 // 工廠基类 class SplitterFactory { public : virtual ISplitter * CreateSplitter()= 0 ; 仮想〜SplitterFactory(){} }。 // 具体类 クラス BinarySplitter:公共ISplitter { }。 クラス TxtSplitter:public ISplitter { }; クラスPictureSplitter:パブリックISplitter { }; クラス VideoSplitter:public ISplitter { }; // 特定工廠 クラス BinarySplitterFactory:public SplitterFactory { public : virtual ISplitter * CreateSplitter(){ return new BinarySplitter(); } }; クラス TxtSplitterFactory:public SplitterFactory { public : virtual ISplitter * CreateSplitter(){ return new TxtSplitter(); } }; クラス PictureSplitterFactory:public SplitterFactory { public : virtual ISplitter * CreateSplitter(){ return new PictureSplitter(); } }; クラス VideoSplitterFactory:public SplitterFactory { public : virtual ISplitter * CreateSplitter(){ return new VideoSplitter(); } }; クラス MainForm:public Form { SplitterFactory *ファクトリ; //工廠 公開: MainFormを(SplitterFactory * 工場){ この - >工場=工場; // 区別するパラメータ関数メンバ } 無効のButton1 Clickを(){ ISplitter *スプリッタ=工場出荷時> CreateSplitter(); // ポリモーフィック新しい新しい スプリッタ> スプリット(); } }; // MainFormは具象クラスに依存しなくなりました
構造
主なポイントのまとめ
- ファクトリメソッドパターンは、クラスオブジェクトのユーザーと特定のタイプの間の結合関係を分離するために使用されます。頻繁に変化する特定のタイプに直面すると、密結合(新規)は脆弱なソフトウェアにつながる可能性があります。
- Factory Methodパターンは、オブジェクト指向のアプローチを使用して、作成される特定のオブジェクトの作業をサブクラスに延期し、それにより、この緊密に結合された関係をより適切に解決する(変更ではなく)拡張戦略を実装します。
- ファクトリメソッドモデルは、「単一オブジェクト」の変化するニーズに対応します。欠点は、作成方法/パラメーターが同じであることです。
基本コード
#include <iostream> using namespace std; クラス商品{ パブリック: 仮想〜製品(){} 仮想 ボイド動作()= 0 ; }; クラス ConcreteProductA:public Product { public : void Operation(){cout << " ConcreteProductA " << endl; } }; クラス ConcreteProductB:public Product { public : void Operation(){cout << "ConcreteProductB 「 << てendl;} }; クラスクリエーター{ パブリック: 仮想製品* FactoryMethod()= 0 ; 仮想〜クリエーター(){} }; クラス ConcreteCreatorA:公共クリエーター{ パブリック: 製品 * FactoryMethodは(){ 返す 新しい(ConcreteProductAを);} }; クラス ConcreteCreatorB:public Creator { public : Product * FactoryMethod(){ return newConcreteProductB(); } }; int main(){ Creator * ca = new ConcreteCreatorA(); 製品 * pa = ca- > FactoryMethod(); pa- > Operation(); // ConcreteProductA Creator * cb = new ConcreteCreatorB(); 製品 * pb = cb-> FactoryMethod(); pb- > Operation(); // ConcreteProductB delete ca; paを削除します。 cbを削除します。 pbを削除します。 0を返し ます。 }