Какой паттерн лучше использовать для описанного случая?

Есть такой вот интерфейс:

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;
}

Ответы (0 шт):