2015-04-28 6 views
4

У меня есть базовый класс 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(), потому что каждый каталог использует свои собственные данные для хранения. Должны ли они быть шаблонами?

Что такое решение? Есть ли какой-либо шаблон программирования, который я пропустил?

+1

Поиск «двойной шаблон отправки C++» в Интернете. –

+0

Я ошибаюсь: разве приготовленные лишние !? Вам нужно только «DataProcessorInterface» –

+0

Каталоги могут быть предоставлены кем-то другим, и DataProcessor может не только помещать данные, но и искать в нем. – DoctorMoisha

ответ

1

Есть два способа сделать это, а также двойную отправку Узор упомянут в комментариях:

Baseline

Первое, что вы указали «базовый» набор координат. Чтобы преобразовать сначала, вы преобразуетесь в базовый набор, а затем преобразуетесь из него.

Преимущества: Вам нужно всего лишь написать toBaseline и fromBaseline для любого количества разных DataProcessor s. Добавление нового DataProcessor так же просто, как его создание, а затем запись преобразования в и из основного набора.

Недостатки: производительность будет страдать, поскольку в большинстве случаев вы выполняете две трансформации. Точность может пострадать из-за потерь в представлении или конверсии.

Transformer объекты

Создайте интерфейс, который преобразует объект из DataProcessor в DataProcessor.

Создайте экземпляр этого интерфейса для каждого поддерживаемого преобразования.

Имейте класс утилиты, который имеет карту исходных и целевых пар для правильного преобразования. Вызовите метод для этого класса утилиты для выполнения преобразования по требованию.

Преимущества: Отсутствие потерь от необходимости проведения нескольких преобразований.

Недостатки: n^2 Transform объектов необходимо создать где n - количество различных объектов DataProcessor. При создании нового DataProcessor вам нужно будет написать и добавить Transform объектов за каждый DataProcessor. Отсутствие Transform s будет обнаружено во время выполнения, а не во время компиляции.

Смежные вопросы