派生类依赖函数

时间:2015-04-28 18:31:08

标签: c++ class oop design-patterns

我有基类DataProcessor。它是某些坐标系中位置计算器的基类。因此,例如,它可以包含以下内容:SphericDataProcessorCartesianDataProcessor。有基类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(),因为每个目录都使用自己的数据来包含。它应该是模板化的吗?

什么是解决方案?我错过了任何编程模式吗?

1 个答案:

答案 0 :(得分:1)

有两种方法可以做到这一点以及评论中提到的Double Dispatch Pattern:

<强>基线

首先,您指定一组“基线”坐标。为了首先转换你转换为核心集,然后你从那里转换。

优点:您只需为任意数量的toBaseline编写fromBaselineDataProcessor。添加新的DataProcessor就像创建它,然后在核心集中编写转换一样简单。

缺点:在大多数情况下,在进行两次转换时,性能会受到影响。由于代表或转换中的损失,准确性可能会受到影响。

变形金刚对象

创建一个将对象从DataProcessor转换为DataProcessor的界面。

为每个支持的转换创建该接口的实例。

让实用程序类具有源和目标对的映射到要使用的正确转换。在该实用程序类上调用方法以按需执行转换。

优点:不必浪费多次转换。

缺点:n ^ 2 Transform个对象需要创建,其中n是不同DataProcessor个对象的数量。创建新DataProcessor时,您需要为添加的每个Transform编写并添加DataProcessor个对象。缺少Transform将在运行时检测到,而不是编译时间。