私たちは、そもそもC ++クラスの最も一般的な実現で始まります
クラスAPI { パブリック: 仮想試験(スタンダード:: 文字列 S)= 0 。 保護: API(){}。 }。 クラス ImpleOne:パブリックAPI { パブリック: 空テスト(文字列 s)はオーバーライド{ のstd :: coutの << " 现在是ワン在执行" << S << はstd ::てendl; } }。 int型メイン(無効) { API * PAPI = 新しいImpleOne(); PAPI- > テスト(); 返します。 }
呼び出し側がAPIとIMPLEONEの存在を知っているので、このコードは、私たちのオブジェクト指向のカプセル化を破壊します。
高い凝集、この要件の低い結合を完了するためにどのように?
そして、ヘッダファイルで私たちの単純なファクトリパターンを見て、と
書式#include <iostreamの> の#include < 文字列 > の#include <地図> // 関数ポインタ確立 のtypedef ボイド *(* コンストラクタ()); // ファクトリを作成。 クラスCObjectFactory { パブリック: // 容器に加え、対応するクラスを登録 静的 ボイド RegsiterClass(STD :: 文字クラス名、コンストラクタコンストラクタ) { コンストラクタ()クラス名] = コンストラクタ; } //はクラスオブジェクトを作成して、返し 静的 ボイド *のCreateObject(CONST STD :: 文字列クラス名) { コンストラクタコンストラクタ = nullptr。 もし(コンストラクタ()(クラス名を見つける。)=!コンストラクタ()の端部()) { コンストラクタ =コンストラクタ()を見つける(クラス名) - >。第二; } であれば(コンストラクタ== nullptr) { 戻りnullptr。 } リターン(* コンストラクタ)(); } プライベート: // 返回一个容器 静的のstd ::マップ<はstd :: 文字列、コンストラクタ>・コンストラクタ() { スタティック地図:: STD <STD :: 文字列、コンストラクタ> インスタンス; 返すインスタンスを; } ;} // 私たちのクラスのマクロ定義登録し ます。#define REG_CLASS(CLASS_NAME)\ クラスCLASS_NAME ##ヘルパー{\ パブリック\: CLASS_NAME ##ヘルパー(){\ CObjectFactory :: RegsiterClass(#1 CLASS_NAME、CLASS_NAMEヘルパー:: CreateObjFunc ##); \ }; \ 静的 ボイド * CreateObjFunc()\ {\ 戻り 新しい新しいCLASS_NAMEを; \ } \ }; \ 静的 CLASS_NAME ##ヘルパーCLASS_NAMEヘルパー##; // 静的を追加するには、ヘッダファイルでのみ有効指します。
どのようにして、このシンプルな植物を呼び出すことです
// ここにクラスの変更、または更新を完了するために、文字列REG_CLASSのCreateObjectを変更し、設定ファイルを直接読み込む、またはにより、変更が背後にあるコードには影響を与えません。 REG_CLASS(ImpleOne) クラスAUTOFACTORY { パブリック: STD :: shared_ptrの <のAPI> CreateAPI() { STD :: shared_ptrの <API> Apipointer(static_castを<API *>(:: CObjectFactoryのCreateObject(" ImpleOne " ))); を返すApipointerを。 } } int型メイン(ボイド) { STD :: shared_ptrの <のAPI> テストポイント(AUTOFACTORY :: CreateAPI()); テストポイント - >テスト("私はあなたの父親じゃない!" ); リターン; }
要約すると:私たちは、私たちが必要とするファクトリクラスとしてクラスを作成することによって提供することができ、および二次登録クラスで、クラスでは私たちは、呼び出し側の内側できない私たちのクラスを知ることによって、私たちの工場を登録する必要があります特定の実装、あなたは彼らが、クラスのよく実現パッケージ必要なクラスを取得することができます。私たちは私たちのクラスの時間を変更したり、交換した後、呼び出し元のコードには影響しません。