我有基类DataProcessor
。它是某些坐标系中位置计算器的基础类。因此,例如,它可以具有诸如SphericDataProcessor
,CartesianDataProcessor
的后代。有一个基类CookedDataCatalogue
,它是某些对象位置的容器的基类。因此,每个DataProcessor
应该能够将其数据放入每个CookedDataCatalogue
中。我可以想象这样的事情:
class CookedDataCatalogue
{
virtual void Transform(DataProcessor* dp) = 0;
virtual void PutData(???) = 0;
}
class CookedDataCatalogue1 : public CookedDataCatalogue
{
void Transform(DataProcessor* dp) override
{
dp->TransformTo(this);
}
}
class CookedDataCatalogue2 : public CookedDataCatalogue
{
...
}
class CookedDataCatalogue3 ...
class DataProcessor
{
virtual void Process() = 0;
virtual void TransformTo(CookedDataCatalogue1* c) = 0;
virtual void TransformTo(CookedDataCatalogue2* c) = 0;
virtual void TransformTo(CookedDataCatalogue3* c) = 0;
}
但是我不喜欢。首先,
void Transform(DataProcessor*)
从基类迁移到所有子类**。其次,如果我将其构建为库,其他用户将无法添加自己的CookedDataUserCatalogue
,因为他无法添加其他void TransformTo(CookedDataUserCatalogue)
。第三,我不知道如何编写函数PutData()
,因为每个目录都使用自己的数据来包含。应该模板化吗?有什么解决办法?有没有我错过的编程模式?
最佳答案
有两种方法可以执行此操作,以及注释中提到的“双调度模式”:
基线
第一个是您指定一组“基准”坐标。为了进行转换,首先要转换为核心集,然后再从中转换。
优点:您只需要为任意数量的不同toBaseline
编写fromBaseline
和DataProcessor
即可。添加新的DataProcessor
就像创建它一样简单,然后在核心集中进行转换。
缺点:在大多数情况下,您进行两次转换会降低性能。由于表示或转换的损失,准确性可能会受到影响。
变压器对象
创建一个将对象从DataProcessor
转换为DataProcessor
的接口(interface)。
为每个受支持的转换创建该接口(interface)的实例。
具有一个实用程序类,该类具有源对和目标对对的映射以使用正确的转换。在该实用工具类上调用一个方法以按需执行转换。
优点:不必因进行多次转换而浪费资源。
缺点:需要创建n ^ 2个Transform
对象,其中n是不同的DataProcessor
对象的数量。创建新的DataProcessor
时,您需要为每个添加的Transform
编写并添加DataProcessor
对象。缺少Transform
s将在运行时而非编译时检测到。