Visitor访问者模式定义
作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.
例如:
Node类接口有三个实现类:File,Directory,Link;
现在需要实现打印方法,但是每个类的具体实现不一样;
可以通过Visitor模式在参与者中加入一个操作,把操作从Node类中分离出来;
void File::accept(Visitor &v){v.visit(this);} void Directory::accept(Visitor &v){v.visit(this);} void Link::accept(Visitor &v){v.visit(this);}
Visitor接口:
class Visitor{
public:
Visitor();
void visit(File*);
void visit(Directory*);
void visit(Link*);
}
void Visitor::visit(File *f){
f->streamOut(cout);
}
void Visitor::visit(Directory *d){
cerr<<"Can't cat a directory."<<endl;
}
void Visitor::visit(Link *l){
l->getSubject()->accept(*this);
}
x现在只要创建一个Visitor并让节点接受它,就可以对任何节点执行cat操作。
Visitor cat;
node->accept(cat);
节点反过来调用Visitor,这个调用会根据节点的实际类型(File,Directory,Link)被解析成对应的visit操作。
这样,如果需要改变打印的方法格式的时候,只需要把“访问Node的权限”授予给另一个类似于Visitor的类。我们可以为每一个新功能从Visitor派生一个子类,并根据每种可访问的节点的类型来实现相应的visit操作。
弊端:如果经常定义新的Node子类,那么为了增加一个相应的visit操作会修改很多类。