行为模式8-访问者模式
访问者模式Visitor
意图
表示一个作用于某个对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
问题思考
一个代码扫描器。我们要进行类型检查、代码优化、变量使用前是否赋值。
适用性
- 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
- 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染*这些对象的类。Visitor使得你可以将相关的操作集中起来定义在一个类中。
- 定义对象结构类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有Visitor的接口在,这可能需要大量工作。如果对象结构类经常改变,那么Visitor可能不适用,还是在这些类中定义这些操作更好。
效果
- 访问者模式使得易于增加新的操作
- 访问者集中相关的操作而分离物管的操作
- 增加新的Element类(被访问者)很困难
- 通过类层次进行访问 一个迭代器(iterator,后面讲)只能对同一类型的元素对象进行操作。Visitor是对不同元素类型的对象结构进行操作。
类图

实现
class Visitor;
class Element {
public:
virtual void Accept(Visitor &v) = 0;
};
class ConcreteElement1;
class ConcreteElement2;
class Visitor {
public:
virtual void VisitConcreteElement1(ConcreteElement1 *element1) = 0;
virtual void VisitConcreteElement2(ConcreteElement2 *element2) = 0;
};
class ConcreteElement1 : public Element {
public:
void Accept(Visitor &v) override {
v.VisitConcreteElement1(this);
}
};
class ConcreteElement2 : public Element {
public:
void Accept(Visitor &v) override {
v.VisitConcreteElement2(this);
}
};
class ConcreteVisitorA : public Visitor {
public:
void VisitConcreteElement1(ConcreteElement1 *element1) override {
std::cout << "type check on element1" << std::endl;
}
void VisitConcreteElement2(ConcreteElement2 *element2) override {
std::cout << "type check on element2" << std::endl;
}
};
class ConcreteVisitorB : public Visitor {
public:
void VisitConcreteElement1(ConcreteElement1 *element1) override {
std::cout << "do performance check on element1" << std::endl;
}
void VisitConcreteElement2(ConcreteElement2 *element2) override {
std::cout << "do performance check on element2" << std::endl;
}
};
注意:使用Visitor模式,必须定义两个类层次:一个对应于接受操作的元素(Element层次),另一个对应于定义元素的操作的访问者(ElementVisitor层次)。给Visitor增加一个子类,即可给Element增加一个操作。如果Element多了一个子类,那么每个Visitor子类要修改接口,增加对该Element的处理。
网友评论