• Visitor Pattern


    1.Visitor模式:将更新(变更)封装到一个类中(访问操作),并由待更改类提供一个接收接口,则可在不破坏类的前提下,为类提供增加新的新操作。

    2.Visitor模式结构图

    Visitor模式的关键是双分派(Double-Dispatch)的技术:Accept()操作是一个双分派的操作,具体调用哪个Accept()操作,有两个决定因素(1)Element类型(2)Visitor类型。

    3.实现

     1 #ifndef _VISITOR_H_
     2 #define _VISITOR_H_ 
     3  
     4 class Element; 
     5 
     6 class Visitor
     7 {
     8 public:
     9     virtual ~Visitor();
    10     virtual void VisitConcreteElementA(Element* elm) = 0;
    11     virtual void VisitConcreteElementB(Element* elm) = 0;
    12 protected:
    13     Visitor();
    14 private:
    15 };
    16 
    17 class ConcreteVisitorA:public Visitor
    18 {
    19 public:
    20     ConcreteVisitorA();
    21     virtual ~ConcreteVisitorA();
    22     virtual void VisitConcreteElementA(Element* elm);
    23     virtual void VisitConcreteElementB(Element* elm);
    24 protected:
    25 private:
    26 }; 
    27 
    28 class ConcreteVisitorB:public Visitor
    29 {
    30 public:
    31     ConcreteVisitorB();
    32     virtual ~ConcreteVisitorB();
    33     virtual void VisitConcreteElementA(Element* elm);
    34     virtual void VisitConcreteElementB(Element* elm);
    35 protected:
    36 private:
    37 }; 
    38 
    39 #endif
    Visitor.h
     1 #include "Visitor.h"
     2 #include "Element.h" 
     3 #include <iostream>
     4 using namespace std;
     5 
     6 Visitor::Visitor()
     7 {
     8 
     9 } 
    10 Visitor::~Visitor()
    11 {
    12 
    13 } 
    14 ConcreteVisitorA::ConcreteVisitorA()
    15 {
    16 
    17 }
    18 ConcreteVisitorA::~ConcreteVisitorA()
    19 {
    20 
    21 }
    22 void ConcreteVisitorA::VisitConcreteElementA(Element* elm)
    23 {
    24     cout<<"i will visit ConcreteElementA..."<<endl;
    25 } 
    26 void ConcreteVisitorA::VisitConcreteElementB(Element* elm)
    27 {
    28     cout<<"i will visit ConcreteElementB..."<<endl;
    29 } 
    30 ConcreteVisitorB::ConcreteVisitorB()
    31 {
    32 
    33 }
    34 ConcreteVisitorB::~ConcreteVisitorB()
    35 {
    36 
    37 } 
    38 void ConcreteVisitorB::VisitConcreteElementA(Element* elm)
    39 {
    40     cout<<"i will visit ConcreteElementA..."<<endl;
    41 } 
    42 void ConcreteVisitorB::VisitConcreteElementB(Element* elm)
    43 {
    44     cout<<"i will visit ConcreteElementB..."<<endl;
    45 }
    Visitor.cpp
     1 #ifndef _ELEMENT_H_
     2 #define _ELEMENT_H_ 
     3 
     4 class Visitor; 
     5 
     6 class Element
     7 {
     8 public:
     9     virtual ~Element();
    10     virtual void Accept(Visitor* vis) = 0;
    11 protected:
    12     Element();
    13 private:
    14 }; 
    15 
    16 class ConcreteElementA:public Element
    17 {
    18 public:
    19     ConcreteElementA();
    20     ~ConcreteElementA();
    21     void Accept(Visitor* vis);
    22 protected:
    23 private:
    24 }; 
    25 
    26 class ConcreteElementB:public Element
    27 {
    28 public:
    29     ConcreteElementB();
    30     ~ConcreteElementB();
    31     void Accept(Visitor* vis);
    32 protected:
    33 private:
    34 }; 
    35 
    36 #endif
    Element.h
     1 #include "Element.h"
     2 #include "Visitor.h" 
     3 #include <iostream>
     4 
     5 using namespace std; 
     6 
     7 Element::Element()
     8 {
     9 
    10 }
    11 Element::~Element()
    12 {
    13 
    14 }
    15 void Element::Accept(Visitor* vis)
    16 {
    17 
    18 } 
    19 ConcreteElementA::ConcreteElementA()
    20 {
    21 
    22 } 
    23 ConcreteElementA::~ConcreteElementA()
    24 {
    25 
    26 } 
    27 void ConcreteElementA::Accept(Visitor* vis)
    28 {
    29     vis->VisitConcreteElementA(this);
    30     cout<<"visiting ConcreteElementA..."<<endl;
    31 } 
    32 ConcreteElementB::ConcreteElementB()
    33 {
    34 
    35 }
    36 ConcreteElementB::~ConcreteElementB()
    37 {
    38 
    39 } 
    40 void ConcreteElementB::Accept(Visitor* vis)
    41 {
    42     cout<<"visiting ConcreteElementB..."<<endl;
    43     vis->VisitConcreteElementB(this);
    44 }
    Element.cpp
     1 #include "Element.h"
     2 #include "Visitor.h" 
     3 #include <iostream>
     4 
     5 using namespace std; 
     6 
     7 int main(int argc,char* argv[])
     8 {
     9     Visitor* vis = new ConcreteVisitorA();
    10     Element* elm = new ConcreteElementA();
    11     elm->Accept(vis); 
    12 
    13     return 0;
    14 }
    main.cpp

    4.Visitor模式的缺点

    (1)破坏了封装性

    (2)ConcreteElement的扩展很困难:每增加一个Element的子类,就要修改Visitor的接口,使得可以提供给这个新增加的子类的访问机制。

  • 相关阅读:
    正则如何匹配div下的所有<li>标签?
    日历
    生成一定数量的不重复随机数
    PHP微信红包的算法实现探讨
    Flask 快速使用 —— (1)
    Django rest framework(8)---- 视图和渲染器
    Django 组件之 ----- content-type
    Django rest framework(7)----分页
    Django rest framework(6)----序列化(2)
    Django rest framework(5)----解析器
  • 原文地址:https://www.cnblogs.com/programmer-wfq/p/4671316.html
Copyright © 2020-2023  润新知