Est-il possible d'implémenter le Visitor Pattern en respectant le Open/Closed Principle, tout en pouvant toujours ajouter de nouvelles classes visitables? Le principe ouvert/fermé stipule que «les entités logicielles (classes, modules, fonctions, etc.) doivent être ouvertes pour l'extension, mais fermées pour modification».Modèle de visiteur + principe ouvert/fermé
struct ConcreteVisitable1;
struct ConcreteVisitable2;
struct AbstractVisitor
{
virtual void visit(ConcreteVisitable1& concrete1) = 0;
virtual void visit(ConcreteVisitable2& concrete2) = 0;
};
struct AbstractVisitable
{
virtual void accept(AbstractVisitor& visitor) = 0;
};
struct ConcreteVisitable1 : AbstractVisitable
{
virtual void accept(AbstractVisitor& visitor)
{
visitor.visit(*this);
}
};
struct ConcreteVisitable2 : AbstractVisitable
{
virtual void accept(AbstractVisitor& visitor)
{
visitor.visit(*this);
}
};
Vous pouvez mettre en œuvre un certain nombre de classes qui dérive de AbstractVisitor: Il est ouvert pour l'extension. Vous ne pouvez pas ajouter une nouvelle classe visitable car les classes dérivées de AbstractVisitor ne compileront pas: Elle est fermée pour modification. L'arborescence de classe AbstractVisitor respecte le principe ouvert/fermé. L'arborescence de classes AbstractVisitable ne respecte pas le principe Ouvert/Fermé, car il ne peut pas être étendu.
Existe-t-il une autre solution que d'étendre AbstractVisitor et AbstractVisitable comme indiqué ci-dessous?
struct ConcreteVisitable3;
struct AbstractVisitor2 : AbstractVisitor
{
virtual void visit(ConcreteVisitable3& concrete3) = 0;
};
struct AbstractVisitable2 : AbstractVisitable
{
virtual void accept(AbstractVisitor2& visitor) = 0;
};
struct ConcreteVisitable3 : AbstractVisitable2
{
virtual void accept(AbstractVisitor2& visitor)
{
visitor.visit(*this);
}
};