Какой паттерн лучше использовать для описанного случая?
Есть такой вот интерфейс:
class ISettings
{
public:
ISettings() = default;
virtual ~ISettings() = default;
virtual bool isValid() const = 0;
};
И два класса, которые реализуют этот интерфейс (также содержат и другую логику):
1 класс
class AudioSettings : public ISettings
{
public:
AudioSettings();
virtual ~AudioSettings() override;
bool isValid() const override;
void setBitRate(int val) const;
void setSampleRate(int val) const;
int bitRate() const;
int sampleRate() const;
// ...
private:
int m_bitRate{0};
int m_sampleRate{0};
// ...
};
2 класс
class VideoSettings : public ISettings
{
public:
VideoSettings();
virtual ~VideoSettings() override;
bool isValid() const override;
int width() const;
int height() const;
// ...
private:
int m_width{0};
int m_height{0};
// ...
};
Теперь представьте, что существует класс кодировщика (Encoder), который при получении определенного класса настроек выполняет определенную логику и, самое главное, обращается к методам определенного класса настроек.
Давайте опишем эту ситуацию:
class Encoder
{
public:
Encoder(ISettings* settings);
~Encoder();
bool init();
// Другие методы ...
private:
ISettings* p_settings{nullptr};
// ...
};
Encoder::Encoder(ISettings* settings)
: p_settings(settings)
{}
bool Encoder::init()
{
if (p_settings && p_settings->isValid()) {
// Логика определения типа настоек
// ...
return true;
}
return false;
}
Вот тут-то и возникает проблема. Поскольку мы предоставляем только интерфейс, кодировщику необходимо точно определить, какой объект получен, и, если он успешно определен, обработать этот объект.
Описание примера:
- Если мы передаем настройки звука, то при обработке объекта, кодировщик должен получить информацию о частоте дискретизации.
int main()
{
AudioSettings* settings = new AudioSettings;
settings->setBitRate(64000);
settings->setSampleRate(44100);
Encoder* encoder = new Encoder(settings);
if (encoder->init()) {
// ...
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
Существует ли паттерн или логика определения типа объекта и как ее можно реализовать интеллигентно :)
Я так понимаю, что в какой-то момент, в любом случае, нам придется использовать преобразование объекта в тот объект, который нам нужен (всего лишь псевдокод):
bool Encoder::init()
{
if (p_settings && p_settings->isValid()) {
// Логика определения типа настоек (в нашем случае мы определили, что были получены настройки звука)
AudioSettings* audioSettings = static_cast<AudioSettings*>(p_settings);
if (audioSettings->bitRate() == 64000) {
// ...
}
// ...
return true;
}
return false;
}