读书笔记:c++对话系列,Visitor模式
需要在类体系中加入一个新的虚函数,但不允许改动。
Visitor模式,核心是:将操作作为数据对象传递给类体系预留的Accept函数。
class Personnel{
public:
virtual void Pay () = 0;
virtual void Promote() = 0;
virtual void Accept(Visitor &) = 0;
};
class Officer : public Personnel { /* 改写虚拟函数 */ };
class Captain : public Officer { /* 改写虚拟函数 */ };
class First : public Officer { /* 改写虚拟函数 */ };
Visitor模式:行为型设计模式。允许为对象结构的元素添加进一步的操作,而不必修改这些元素的类。以下为示例:
class Element {
public:
virtual ~Element() {}
virtual void accept(class Visitor &v) = 0;
};
class ConcreteElementA : public Element {
public:
void accept(Visitor &v) override{v.visit(*this);}
void operationA() {
std::cout << "Element A operation." << std::endl;
}
};
class ConcreteElementB : public Element {
public:
void accept(Visitor &v) override{v.visit(*this);}
void operationB() {
std::cout << "Element B operation." << std::endl;
}
};
class Visitor {
public:
virtual ~Visitor() {}
virtual void visit(ConcreteElementA &element) = 0;
virtual void visit(ConcreteElementB &element) = 0;
};
class ConcreteVisitor : public Visitor {
public:
void visit(ConcreteElementA &element) override {
element.operationA();
std::cout << "Visited by ConcreteVisitor." << std::endl;
}
void visit(ConcreteElementB &element) override {
element.operationB();
std::cout << "Visited by ConcreteVisitor." << std::endl;
}
};
class NewOperationVisitor : public Visitor { //这个就是新增的操作范例
public:
void visit(ConcreteElementA &element) override {
std::cout << "New operation visited Element A." << std::endl;
}
void visit(ConcreteElementB &element) override {
std::cout << "New operation visited Element B." << std::endl;
}
};
int main() {
ConcreteElementA elementA;
ConcreteElementB elementB;
ConcreteVisitor visitor; //原操作
elementA.accept(visitor);
elementB.accept(visitor);
NewOperationVisitor newOperationVisitor;//这个就是新增的操作范例
elementA.accept(newOperationVisitor);
elementB.accept(newOperationVisitor);
return 0;
}
以下为改写前面的代码
class Visitor {
public:
virtual void Visit( Personnel& ) = 0;
virtual void Visit( Officer& ) = 0;
virtual void Visit( Captain& ) = 0;
virtual void Visit( First& ) = 0;
};
void Personnel::Accept( Visitor & v ) { v.Visit( *this ); }
void Officer::Accept ( Visitor & v ) { v.Visit( *this ); }
void Captain::Accept ( Visitor & v ) { v.Visit( *this ); }
void First::Accept ( Visitor & v ) { v.Visit( *this ); }
class DoSomething : public Visitor {
public:
virtual void Visit( Personnel& );
virtual void Visit( Officer& );
virtual void Visit( Captain& );
virtual void Visit( First& );
};
void DoSomething::Visit( Captain& c ){
if( femaleGuestStarIsPresent )
c.TurnOnCharm();
else
c.StartFight();
}
void DoSomething::Visit( First& f ){
f.RaiseEyebrowAtCaptainsBehavior();
}
void f( Personnel& p ){
p.Accept( DoSomething() );
}
int main(){
Captain k;
First s;
f( k );
f( s );
}