Visitor Pattern with C++
访问者模式 C++实现
访问者模式,顾名思义就是使用vistor类来访问其他类的intern数据,而不改变intern的数据结构和代码。 这样可以分开数据显示和业务逻辑,使得代码更加清晰。
访问者模式的优点就是:灵活度非常高,有优秀的拓展性。 缺点就是:不依赖抽象元素,违反了依赖倒置的原则,直接依赖实现类,拓展实现类比较难。
访问者模式和迭代器模式有相同点又有不同点。 相同点都是访问具体的实现类。 不同点在于迭代器模式只能访问相同由base class引用来的class或者interface的数据,而访问者模式可以访问不同的class,不再依赖base class
#####总的来说 访问者模式适用范围大于迭代器模式的范围!
下面这种方式是使用不同访问者定义不同的访问方式,可以说是多个访问者。
#include
#include
#include
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<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;
}
};
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 );
}
</code></pre>
在vistor模式中,以及以前的design pattern中,我们都使用了动态绑定!
动态绑定就是在基类中定义virtual function 然后继承该base class,创建derive class时转到base class。当我们使用derive class中的function,我们只需要把base class指针指向该函数即可!
> 我们要分清函数重载与动态绑定在工程中的区别(重载只是函数类型不同而已!)
> 动态绑定中,函数的执行操作决定于请求种类,与接收者类型!
访问者模式适合于重构!比如功能集中化,UI集中化。