读书笔记: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 );
}

你可能感兴趣的:(cpp,c++)