Подскажите пожалуйста какой вариант предпочтительнее и почему?
Есть некие сообщения слажащие для взаимодействия разных частей системы. Все имеют одинаковый интерфейс, все наследники одного предка( Imessage в данном примере ). Нажно перед собственно началом взаимодействия проводить проверку Валидности сообщения. Вобпрос как наиболее "правильно" это сделать? Видиться 2 основных способа:
1. Каждый проверяет себя сам
struct Imessage
{
virtual bool isValid() const = 0;
};
struct MessageType1 : public Imessage
{
virtual bool isValid() const
{
//реализация
};
};
struct MessageType2 : public Imessage
{
virtual bool isValid() const
{
//реализация
};
};
Приемущества — 1 виртуальный вызов. Вся информация инкапсулирована.
Недостатки — хочется что бы конкретные наследники Imessage'a были максимально просты, были только сообщениями, а не "монстрами". Остается под вопросом, на сколько само сообщения должно знать признаки своей валидности
2. Паттерн Visitor
struct MessageType1;
struct MessageType2;
class IChecker
{// в наследнике проверяются условия валидности
virtual bool CheckType1(MessageType1&) = 0;
virtual bool CheckType2(MessageType2&) = 0;
}
struct MessageType1 : public Imessage
{
virtual bool VisitChecker(IChecker& refIChecker) const
{
return refIChecker.CheckType1( *this );// придет барин, барин нас рассудит
};
};
struct MessageType2 : public Imessage
{
virtual bool VisitChecker(IChecker& refIChecker) const
{
return refIChecker.CheckType2( *this );// придет барин, барин нас рассудит
};
};
Преимущества — сообщения остаются максимально просты, знают о себе неаобходимый минимум, и служат, как и прежде, только для выбора варианта обработки.
Недостатки — типичные недостатки паттерна Visitor — 2 виртыальных вызова, созможно излишняя громоздкость.
(Кстати в этом варианте есть возможность для каждого наследника IChecker проверять свои условия валидности. в данный момент это не нужно, но то же не бесполезное приемущество)
Какой вариант наиболее предпочтителен и почему ? Есть ли другие адекватные варианты?(здесь конечно можно добавить некий type id для каждого сообщения и где то сделать большой switch
вся отсальная обработка строится через паттерн Visitor, по этому это а) не уместно б) не объектно-оринтированно
))
PS Конечно это не совсем в этот раздел, тк собственно по особенностям с++ здесь вопросов нет, но все же.