C++编程思想 第2卷 第10章 设计模式 多重派遣 用访问者模式进行多重派遣

访问者模式的目标是将类继承层次结构上的操作与这个层次结构本身分开
面向对象编程所做的大部分工作是将数据和操作组合在一起形成对象
并利用多态性根据对象的确切类型自动选择操作的正确变化

访问者模式允许创建一个独立的类层次结构Visitor从而有效地对主类接口进行扩展
这个独立的类层次结构将主类上的各种操作 "虚化"

//: C10:BeeAndFlowers.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Demonstration of "visitor" pattern.
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cstdlib>
#include "../purge.h"
using namespace std;

class Gladiolus;
class Renuculus;
class Chrysanthemum;

class Visitor {
public:
  virtual void visit(Gladiolus* f) = 0;
  virtual void visit(Renuculus* f) = 0;
  virtual void visit(Chrysanthemum* f) = 0;
  virtual ~Visitor() {}
};

class Flower {
public:
  virtual void accept(Visitor&) = 0;
  virtual ~Flower() {}
};

class Gladiolus : public Flower {
public:
  virtual void accept(Visitor& v) {
    v.visit(this);
  }
};

class Renuculus : public Flower {
public:
  virtual void accept(Visitor& v) {
    v.visit(this);
  }
};

class Chrysanthemum : public Flower {
public:
  virtual void accept(Visitor& v) {
    v.visit(this);
  }
};

// Add the ability to produce a string:
class StringVal : public Visitor {
  string s;
public:
  operator const string&() { return s; }
  virtual void visit(Gladiolus*) {
    s = "Gladiolus";
  }
  virtual void visit(Renuculus*) {
    s = "Renuculus";
  }
  virtual void visit(Chrysanthemum*) {
    s = "Chrysanthemum";
  }
};

// Add the ability to do "Bee" activities:
class Bee : public Visitor {
public:
  virtual void visit(Gladiolus*) {
    cout << "Bee and Gladiolus" << endl;
  }
  virtual void visit(Renuculus*) {
    cout << "Bee and Renuculus" << endl;
  }
  virtual void visit(Chrysanthemum*) {
    cout << "Bee and Chrysanthemum" << endl;
  }
};

struct FlowerGen {
  Flower* operator()() {
    switch(rand() % 3) {
      default:
      case 0: return new Gladiolus;
      case 1: return new Renuculus;
      case 2: return new Chrysanthemum;
    }
  }
};

int main() {
  srand(time(0)); // Seed the random number generator
  vector<Flower*> v(10);
  generate(v.begin(), v.end(), FlowerGen());
  vector<Flower*>::iterator it;
  // It's almost as if I added a virtual function
  // to produce a Flower string representation:
  StringVal sval;
  for(it = v.begin(); it != v.end(); it++) {
    (*it)->accept(sval);
    cout << string(sval) << endl;
  }
  // Perform "Bee" operation on all Flowers:
  Bee bee;
  for(it = v.begin(); it != v.end(); it++)
    (*it)->accept(bee);
  purge(v);
  getchar();
} ///:~

输出
Chrysanthemum
Chrysanthemum
Gladiolus
Chrysanthemum
Renuculus
Gladiolus
Gladiolus
Renuculus
Renuculus
Gladiolus
Bee and Chrysanthemum
Bee and Chrysanthemum
Bee and Gladiolus
Bee and Chrysanthemum
Bee and Renuculus
Bee and Gladiolus
Bee and Gladiolus
Bee and Renuculus
Bee and Renuculus
Bee and Gladiolus

Flower是主层次结构
Flower的各个子类通过函数accept()得到一个Visitor
Flower主层次结构除了函数accept()外没有别的操作
因此Flower层次结构的所有功能都包含在Visitor层次结构中

猜你喜欢

转载自blog.csdn.net/eyetired/article/details/82622982