访问者模式,顾名思义就是使用vistor类来访问其他类的intern数据,而不改变intern的数据结构和代码。
这样可以分开数据显示和业务逻辑,使得代码更加清晰。
访问者模式的优点就是:灵活度非常高,有优秀的拓展性。
缺点就是:不依赖抽象元素,违反了依赖倒置的原则,直接依赖实现类,拓展实现类比较难。
访问者模式和迭代器模式有相同点又有不同点。
相同点都是访问具体的实现类。
不同点在于迭代器模式只能访问相同由base class引用来的class或者interface的数据,而访问者模式可以访问不同的class,不再依赖base class
中的来说 访问者模式适用范围大于迭代器模式的范围!
下面这种方式是使用不同访问者定义不同的访问方式,可以说是多个访问者。
#include <iostream> #include <string> #include <list> using namespace std; class BaseElement; class BaseVisitor { public: virtual void Visit( BaseElement *element ){}; }; class BaseElement { public: // Methods virtual void Accept( BaseVisitor *visitor ){}; }; // "ConcreteElement" class Employee : public BaseElement { public: string name; double income; int vacationDays; public : Employee( string name, double income, int vacationDays ) { this->name = name; this->income = income; this->vacationDays = vacationDays; } void Accept( BaseVisitor *visitor ) { visitor->Visit( this ); } }; class IncomeVisitor : public BaseVisitor { public: void Visit( BaseElement *element ) { Employee *employee = ((Employee*)element); employee->income *= 1.10; cout<<employee->name<<" 's new income: " <<employee->income<<endl; } }; class VacationVisitor : public BaseVisitor { public : void Visit( BaseElement *element ) { Employee *employee = ((Employee*)element); employee->vacationDays += 3; cout<<employee->name<<" 's new vacation days: " <<employee->vacationDays<<endl; } }; // "ObjectStructure" class Employees { private : list< Employee*> employees; public : void Attach( Employee *employee ) { employees.push_back(employee); } void Detach( Employee *employee ) { employees.remove(employee); } void Accept( BaseVisitor *visitor ) { for (std::list<Employee*>::iterator it=employees.begin(); it != employees.end(); ++it) (*it)->Accept(visitor); } }; void main( ) { Employees *e = new Employees(); e->Attach( new Employee( "Jason", 25000.0, 14 ) ); e->Attach( new Employee( "Albter", 35000.0, 16 ) ); e->Attach( new Employee( "lily", 45000.0, 21 ) ); IncomeVisitor *v1 = new IncomeVisitor(); VacationVisitor *v2 = new VacationVisitor(); e->Accept( v1 ); e->Accept( v2 ); }
在vistor模式中,以及以前的design pattern中,我们都使用了动态绑定!
动态绑定就是在基类中定义virtual function 然后继承该base class,创建derive class时转到base class。当我们使用derive class中的function,我们只需要指向该函数即可!
我们要分清函数重载与动态绑定在工程中的区别(重载只是函数类型不同而已!)
动态绑定中,函数的执行操作决定于请求种类,与接收者类型!
访问者模式适合于重构!比如功能集中化,UI集中化。