标签:
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
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 }
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
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 }
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 }
4.Visitor模式的缺点
(1)破坏了封装性
(2)ConcreteElement的扩展很困难:每增加一个Element的子类,就要修改Visitor的接口,使得可以提供给这个新增加的子类的访问机制。
标签:
原文地址:http://www.cnblogs.com/programmer-wfq/p/4671316.html