Допустим есть интерфейс MyInterfaceV1, который используется в большом количестве существующего кода, и также большое количество классов, реализующих этот интерфейс. Мы хотим добавить к нему пару методов, для реализации некой новой функциональности. Но MyIntefaceV1 изменить нельзя.
Предлагается сделать следующее. Создается MyIntefaceV2, унаследованный от MyInterfaceV1:
class MyInterfaceV2 : public MyInterfaceV1
{
public:
// методы для новой функциональности ...
};
Новые классы реализуют оба интерфейса:
class ConcreteV2 : public MyInterfaceV2
{
public:
// MyInterfaceV1 methods
...
// MyInterfaceV2 methods
...
};
Потом они передаются в функции, ожидающие MyInterfaceV1:
void foo(MyIntefaceV1 * obj) { ... }
ConcreteV2 * obj = new ConcreteV2();
foo(obj);
Код, который не знает про MyIntefaceV2, продолжает использовать MyInterfaceV1 как и раньше. А код, который хочет задействовать MyInterfaceV2, делает следующее:
void bar(MyInterfaceV1 * obj)
{
if (MyInterfaceV2 * objv2 = dynamic_cast<MyInterfaceV2 *>(obj))
{
// используем MyInterfaceV2
}
}
Вопрос: насколько хорошо такое решение через dynamic_cast? Есть ли другие варианты?