Hello.
Есть базовые классы
class COption
{
};
class CConnection
{
public:
virtual void ApplyOption(COption const & option) = 0;
};
От CConnection — куча разных наследников, в том числе здесь нужна
расширяемость. Поэтому COption не должен знать устройства каких-либо
CConnection.
То есть мы должны иметь возможность применять одну и ту же опцию к
разным реализация CConnection:
class COptionA : public COption {};
class CConnectionA : public CConnection {...};
class CConnectionB : public CConnection {...};
CConnectionA a;
a.ApplyOption(COptionA());
CConnectionB b;
b.ApplyOption(COptionA());
Остается тогда передать знание о внутренностях опции реализациям
CConnection, чтобы они сами умели применять опцию к себе.
Но содержимое у опций может быть абсолютно разное. То есть общего
интерфеса, предоставляющего доступ ко внутренностям опции у COption не
может быть. А конкретные реализации CConnection умеют применять к себе
только конкретные опции, о которых они знают, то есть первое, что
приходит в голову — это:
class CConnectionA : public CConnection
{
public:
void Apply(COptionA const &);
void Apply(COptionC const &);
void ApplyOption(COption const & option)
{
if (dynamic_cast<COptionA const *>(&option))
{
Apply(*dynamic_cast<COptionA const *>(&option));
}
else if (dynamic_cast<COptionC const *>(&option))
{
Apply(*dynamic_cast<COptionC const *>(&option));
}
}
};
Вот. Но у меня уже за время изучения паттернов выработалась неприязнь
к dynamic_cast. Есть ли здесь решение без использования dynamic_cast ?
Вроде бы чем-то напоминает visitor, но тот завязан на фиксированное
количество "посещаемых", а здесь количество наследников CConnection и
COption будет в будущем расти, при этом старый код ОЧЕНЬ хотелось бы
не трогать при добавлении наследников.
--
Igor Polyakov — igorpol_gbt (at) mail (dot) ru
Posted via RSDN NNTP Server 1.9