設計模式學習(C++實現)17——訪問者模式

概述

當我們存在一些固定的元素組合,而有一些針對這些元素的訪問者,每個訪問者針對不同的元素有不同的處理,這時候就可以採用訪問者模式。例如,電影院在放映三場電影,有很多觀衆回去看,並且給予不同的評價,這裏三場電影就是固定元素,觀衆就是訪問者;再比如,系統的某個模塊收到了一些固定的數據,有不同的模塊需要訪問並進行不同的處理,這裏數據就是固定元素,不同模塊是訪問者。

代碼實現


class Element {
public:
  explicit Element(std::string name) : name_(name) {}

  virtual ~Element() = default;

  std::string GetName() { return name_; }

  virtual void SomeOperation() = 0;

protected:
  std::string name_;
};

class Element_1 : public Element {
public:
  explicit Element_1(std::string name) : Element(name) {}

  void SomeOperation() override {
    std::cout << "Hi, I'm element 1." << std::endl;
  }
};

class Element_2 : public Element {
public:
  explicit Element_2(std::string name) : Element(name) {}

  void SomeOperation() override {
    std::cout << "Hi, I'm element 2." << std::endl;
  }
};

class Visitor {
public:
  virtual void ProcessElement(Element &element) = 0;
};

class Visitor_1 : public Visitor {
public:
  void ProcessElement(Element &element) override {
    std::cout << "I want element 1." << std::endl;
    if (element.GetName() == "element1") {
      element.SomeOperation();
    }
  };
};

class Visitor_2 : public Visitor {
public:
  void ProcessElement(Element &element) override {
    std::cout << "I want element 2." << std::endl;
    if (element.GetName() == "element2") {
      element.SomeOperation();
    }
  };
};

class ElementAggregation {
public:
  void Add(const Element &element) { elements_.emplace_back(element); }

  void AcceptVisitor(Visitor *visitor) {
    for (auto &ele : elements_) {
      visitor->ProcessElement(*ele);
    }
  }

private:
  std::vector<std::unique_ptr<Element>> elements_;
};

int main() {
  ElementAggregation aggregation;
  aggregation.Add(Element_1("element1"));
  aggregation.Add(Element_2("element2"));
  Visitor *visitor_1 = new Visitor_1();
  Visitor *visitor_2 = new Visitor_2();
  aggregation.AcceptVisitor(visitor_1);
  aggregation.AcceptVisitor(visitor_2);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章