The visitor pattern is to add new interfaces to fixed interfaces. One of the biggest drawbacks of the visitor pattern is that the class that needs to add interfaces can no longer derive new classes. c + + now has generic functions (overloaded parentheses) to replace this pattern, which is more flexible.
#include <iostream> using namespace std; //Visitor mode not used namespace unVisit { //foo1 and foo2 are the original interfaces, but now we need to add foo3. class Composite { public: virtual void foo1() = 0; virtual void foo2() = 0; virtual void foo3() = 0; //New code }; class Composite1 : public Composite { public: void foo1() override { cout << __PRETTY_FUNCTION__ << endl; } void foo2() override { cout << __PRETTY_FUNCTION__ << endl; } //New code void foo3() override { cout << "New function" << endl; } }; class Composite2 : public Composite { public: void foo1() override { cout << __PRETTY_FUNCTION__ << endl; } void foo2() override { cout << __PRETTY_FUNCTION__ << endl; } //New code void foo3() override { cout << "New function" << endl; } }; } namespace Visit { class Composite; class Composite1; class Composite2; //Non generic version class Visit { public: virtual void composite1(Composite &composite) = 0; virtual void composite2(Composite &composite) = 0; }; //functor class Foo { public: virtual void operator()(Composite1 &composite1) = 0; virtual void operator()(Composite2 &composite1) = 0; }; class Composite { public: virtual void foo1() = 0; virtual void foo2() = 0; //Reserved interface (non function like version) virtual void futureFoo(Visit &visit) = 0; //Function like version virtual void operatorFoo(Foo &foo) = 0; }; class Composite1 : public Composite { public: void foo1() override { cout << __PRETTY_FUNCTION__ << endl; } void foo2() override { cout << __PRETTY_FUNCTION__ << endl; } void futureFoo(Visit &visit) override { visit.composite1(*this); } void operatorFoo(Foo &foo) override { foo.operator()(*this); } }; class Composite2 : public Composite { public: void foo1() override { cout << __PRETTY_FUNCTION__ << endl; } void foo2() override { cout << __PRETTY_FUNCTION__ << endl; } void futureFoo(Visit &visit) override { visit.composite2(*this); } void operatorFoo(Foo &foo) override { foo.operator()(*this); } }; //In the future, add an interface and directly create a Visit subclass class Visit1 : public Visit { public: void composite1(Composite &composite) override { cout << "New function" << endl; } void composite2(Composite &composite) override { cout << "New function" << endl; } }; //Create Foo subclass directly after adding interface class Foo1 : public Foo { public: void operator()(Composite1 &composite1) override { cout << "New function" << endl; } void operator()(Composite2 &composite1) override { cout << "New function" << endl; } }; private: //foo can have parameters. } int main() { unVisit::Composite1().foo3(); unVisit::Composite2().foo3(); Visit::Visit1 foo3; Visit::Composite1().futureFoo(foo3); Visit::Composite2().futureFoo(foo3); Visit::Foo1 _foo3; Visit::Composite1().operatorFoo(_foo3); Visit::Composite2().operatorFoo(_foo3); return 0; }
The stable part of the visitor pattern is the interface class Composite, and to ensure that it will not be derived any more. The interface of the variable part of the interface class always needs to add new interfaces.