読んでくれてありがとう。これは、適切な解決策があるという点で厄介な設計上の質問ですが、私があまり経験していないテンプレートを介したより良い方法がないかどうかという質問です。
保存する必要のある一連のタイプのデータテーブル(抽象クラスDataTableから派生)があります。ベクトルDataTable*を格納し、すべてのDataTableIndexに共通の一般的な作業を処理する「DataTableIndex」抽象クラスを作成しました。ルックアップの実行、必要な場合にのみテーブルが読み込まれるようにするプロキシパターンの実装、エラーチェックなどです。
次に、テーブルタイプごとにサブクラス化します。これを行う必要がある唯一の理由は、テーブルタイプごとに、それをロードするために呼び出される特定の関数があるためです。
DataTableには多くのサブクラスがあるため、可能であれば、テンプレートを介してDataTableIndexのこのサブクラス化を避けたいと思います。
class DataTableIndex
{
// various functions to implement lookup, Proxy and error checking
// functionality common to all DataTableIndexes.
// This code needs access to _lookupTable and _theTables
DataTable* getTable( int tableNum );
private:
// These functions call the appropriate user interface function for loading
// a table of the subclass' type.
// They are called by more general non-virtual public functions
virtual bool loadIndex( vector<LookupEntry*>& returnLookupTable ) = 0;
virtual DataTable* loadTable( int tableNum ) = 0;
vector<LookupEntry*> _lookupTable;
vector<DataTable*> _theTables;
UserInterface* UI;
};
このクラスには非常に単純なサブクラスがあり、基本的には、データテーブルのファイルを実際に開いて解析するユーザーインターフェイスクラスの関数を指します。
class TableTypeA_Index : public DataTableIndex
{
virtual bool loadIndex( vector<LookupEntry*>& returnLookupTable )
{
return UI->loadTableAIndex( _lookupTable );
}
virtual DataTable* loadTable( int tableNum )
{
return UI->loadTableTypeA( _lookupTable[ tableNum ] );
}
};
これは適切に機能します。しかし、たとえば「loadTableTypeA」をテンプレートパラメータを介してDataTableIndexに渡すことができるはずなので、サブクラス化する必要はありません。
テンプレートを使用したいもう1つの理由は、DataTable*を常に実際のテーブルタイプにキャストする必要がないことです。コンパイル時にテーブルのタイプを知っていても、dynamic_cast <>を使用してエラーチェックを行う必要があるように感じますが、getTable()の呼び出し元が毎回これを実行する必要はありません(よく呼ばれます)。
私の理想的な解決策は次のとおりです。1)DataTableIndexクラスをテンプレートに一般化し、_lookupTableと_theTablesのLookupEntry*とDataTable*をテンプレートパラメーターで置き換えます。これにより、キャストが不要になります。
2)適切なUI関数をマップして、サブクラス化せずに適切なテーブルタイプをロードします。
だから基本的にはこのクラスを使ってこんな感じにしたいと思います(どういうわけか)
DataTableIndex< LookupEntryTypeAMatlab,
TableTypeA,
loadTableAIndex(),
loadTableTypeA() > theTypeAIndex;
ポリシークラスについて考えましたが、そのアプローチの印象は、この場合、サブクラスを別のクラスに移動するだけであるということでした。