У меня разные посетители для определенных типов объектов. У меня проблема с внедрением общего интерфейса, который может использоваться для всех типов. Какая лучшая архитектура используется в этой ситуации? Я придумал 3 различных решений, но все они выглядят очень некрасиво со мной: (некоторые вещи, как виртуальные деструкторы отбрасываются для простоты)Шаблон посетителя против downcasting с ограничением на тип ввода
class IObject {
virtual void Accept(IVisitor& visior) = 0;
};
class Text: IObject {
void Accept(IVisitor& visitor) {
visitor.Visit(*this);
}
};
class Image: IObject {
void Accept(IVisitor& visitor) {
visitor.Visit(*this);
}
};
class IVisitor {
virtual void Visit(Text& text) = 0;
virtual void Visit(Image& image) = 0;
};
class TextVisitor: IVisitor {
void Visit(Text& text) {
// Do some stuff with text
}
void Visit(Image& image) {
// Image not supported, throw exception
}
};
ИЛИ
class IObject {};
class Text: IObject {};
class Image: IObject {};
class IVisitor {
virtual void Visit(IObject& object) = 0;
};
class TextVisitor: IVisitor {
void Visit(IObject& object) {
Text& text = dynamic_cast<Text&>(object);
// Do some stuff with text
}
};
ИЛИ
template <typename T>
class IVisitor {
virtual void Visit(T& object) = 0;
};
class TextVisitor: IVisitor<Text> {
void Visit(Text& text) {
// Do some stuff
}
};
class ImageVisitor: IVisitor<Image> {
void Visit(Image& image) {
// Do some stuff
}
};
class ITextImagelVisitor: IVisitor<Text>, IVisitor<Image> {};
class VisitorDispatcher: ITextImageVisitor {
void Visit(Text& text) {
text_visitor_->Visit(text);
}
void Visit(Image& image) {
image_visitor_->Visit(image);
}
std::shared_ptr<IVisitor<Text>> text_visitor_;
std::shared_ptr<IVisitor<Image>> image_visitor_;
};
class IObject {
virtual void Accept(ITextImageVisitor& visior) = 0;
};
class Text: IObject {
void Accept(ITextImageVisitor& visitor) {
visitor.Visit(*this);
}
};
class Image: IObject {
void Accept(ITextImageVisitor& visitor) {
visitor.Visit(*this);
}
};
В классическом (GoF) шаблоне посетителей используется подход №1. Это также, безусловно, предпочтительнее №2. Что вам не нравится в этом? – Angew