提前感谢您的阅读。这是一个挑剔的设计问题,因为我有一个足够的解决方案,但如果没有更好的模板方式,我对此不是很有经验。
我需要存储一系列类型的数据表(派生自抽象类 DataTable)。我编写了一个“DataTableIndex”抽象类,它存储一个向量 DataTable* 并处理所有 DataTableIndexes 共有的一般工作——进行查找、实现代理模式以便仅在需要时加载表、错误检查等。
然后我为每个表类型子类化它,我需要这样做的唯一原因是因为每个表类型都有一个特定的函数可以调用来加载它。
如果可能的话,我想通过模板以某种方式避免这种 DataTableIndex 的子类化,因为 DataTable 有很多子类。
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,所以我不必对它进行子类化。
我想使用模板的另一个原因是我不想一直将 DataTable* 强制转换为实际的表类型。即使我在编译时知道它应该是什么类型的表,我觉得我应该使用 dynamic_cast<> 进行错误检查,但我不希望 getTable() 的调用者每次都必须这样做(它经常被调用)。
我理想的解决方案是: 1) 将 DataTableIndex 类泛化为模板,用模板参数替换 _lookupTable 和 _theTables 中的 LookupEntry* 和 DataTable*。这将消除铸造。
2) 映射适当的 UI 函数以加载正确的表类型,无需子类化。
所以基本上我想使用这个类看起来像这样(不知何故)
DataTableIndex< LookupEntryTypeAMatlab,
TableTypeA,
loadTableAIndex(),
loadTableTypeA() > theTypeAIndex;
我对策略类进行了一些思考,但我对这种方法的印象是,在这种情况下,我只是将子类化移动到其他东西。