访问者模式(visitor)c++版本(设计模式完)
2017-11-16 15:24
459 查看
这是大话设计模式中的访问者模式的c++版本
程序输出:
以下内容摘抄自《设计模式》:
访问者模式适用性:
1.一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
2.需要对一个对象结构中的对象进行很多不同且不相关的操作,而你想避免让这些操作“污染”这些对象的类,visitor使得你可以将相关的操作集中起来定义在一个类中。
3.定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,者可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作比较好。
访问者模式的优点:
1.访问者模式易于增加新的操作 访问者使得增加以来于复杂对象结构的构建的操作变得更容易了。仅需增加一个新的访问者即可在一个对象结构上定义一个新的操作。相反,如果每个功能都分散在多个类智商的话,定义新的操作时必须修改每一个类。
2.访问者集中相关的操作而分离无关的操作 相关的行为不是分布在定义该对象结构的各个类上,而是集中在一个访问者中。无关行为却被分别放在它们各自的访问者子类中。这就简化了这些元素的类,也简化了在这些访问者中定义的算法。所有与它的算法相关的数据结构都可以被隐藏在访问者中。
3.访问限制少 可以访问不具有相同父类的对象。可以对一个visitor接口增加任何类型的对象,它们不必继承相同的父类。
4.积累状态 当访问者访问对象结构中的每一个元素时,它可能会积累状态。如果没有访问者,这一状态将作为额外的参数传递给进行遍历的操作,或者定义为全局变量。
访问者模式的缺点:
1.增加新的ConcreteElement类很困难 visitor模式使得难以增加新的Element的子类。每添加一个新的ConcreteElement都要visitor中添加一个新的抽象操作,并在每一个ConcretVisitor类中实现相应操作。
2.破坏封装 访问者方法嘉定ConcreteElement接口的功能足够强,足以让访问者进行它们的工作。结果时,该模式常常迫使你提供访问元素内部状态的公共操作,这可能会破坏它们的封装性。
转载请注明源地址:http://blog.csdn.net/clh01s
/* * visitor.cpp * * Created on: Nov 16, 2017 * Author: clh01s@163.com * 访问者模式:表示一个作用于某对象结构中的各个元素的操作。 * 它使你可以在不改变各个元素的类的前提下定义 * 作用于这些元素的新操作。 */ #include <iostream> #include <string> #include <vector> using namespace std; class Man; class Woman; //状态的抽象类 class Action { public: virtual ~Action(){} virtual void GetManConclusion(Man* concreteElement)=0; virtual void GetWomanConclusion(Woman* concreteElement)=0; }; //男人女人的抽象类 class Person { public: virtual ~Person(){} //获得状态对象 virtual void Accept(Action* visitor)=0; }; class Man:public Person { public: //实现基类虚函数 void Accept(Action* visitor) override { /* 首先在客户程序中将具体状态作为参数传递给 * “男人”类完成了一次分派,然后“男人”类调 * 用作为参数的“具体状态”中的方法“男人反应” * 同时将自己(this)作为参数传递进去,完成 * 了二次分派。 */ visitor->GetManConclusion(this); } string GetGender(){return _gender;} private: string _gender = "男人"; }; class Woman:public Person { public: //实现基类虚函数 void Accept(Action* visitor) override { visitor->GetWomanConclusion(this); } string GetGender(){return _gender;} private: string _gender = "女人"; }; //成功 class Success:public Action { public: void GetManConclusion(Man* concreteElement) override { cout<<concreteElement->GetGender()<<"成功时,背后多半有个伟大的女人。"<<endl; } void GetWomanConclusion(Woman* concreteElement) override { cout<<concreteElement->GetGender()<<"成功时,背后多半有个不成功的男人。"<<endl; } }; //失败 class Failing:public Action { public: void GetManConclusion(Man* concreteElement) override { cout<<concreteElement->GetGender()<<"失败时,闷头喝酒,谁也不用劝。"<<endl; } void GetWomanConclusion(Woman* concreteElement) override { cout<<concreteElement->GetGender()<<"失败时,两眼泪汪汪,谁也劝不了。"<<endl; } }; //恋爱 class Amativeness:public Action { public: void GetManConclusion(Man* concreteElement) override { cout<<concreteElement->GetGender()<<"恋爱时,不懂也要装懂。"<<endl; } void GetWomanConclusion(Woman* concreteElement) override { cout<<concreteElement->GetGender()<<"恋爱时,懂也要装不懂。"<<endl; } }; //婚姻 class Marriage:public Action { public: void GetManConclusion(Man* concreteElement) override { cout<<concreteElement->GetGender()<<"结婚时,感慨道:恋爱游戏终结时,‘有妻徒刑’遥无期。"<<endl; } void GetWomanConclusion(Woman* concreteElement) override { cout<<concreteElement->GetGender()<<"结婚时,欣慰曰:爱情长跑路漫漫,婚姻保险保平安。"<<endl; } }; //对象结构 class ObjectStructure { public: //添加 void Attach(Person* person) { _elements.push_back(person); } //删除 void Detach(Person* person) { if(!_elements.empty()) { for(int i = 0;i != _elements.size();++i) { if(_elements[i] == person) { _elements.erase(_elements.begin()+i); } } }else { cout<<"对象向量中没有元素请检查操作是否正确."<<endl; } } void Display(Action* visitor) { //遍历向量中存放的所有元素,调用accept for(auto i : _elements) { i->Accept(visitor); } } private: vector<Person*> _elements; }; int main() { ObjectStructure object; object.Attach(new Man()); object.Attach(new Woman()); //成功反应 Success* v1 = new Success(); //显示反应 object.Display(v1); //失败反应 Failing* v2 = new Failing(); //显示反应 object.Display(v2); //恋爱反应 Amativeness* v3 = new Amativeness(); //显示反应 object.Display(v3); //结婚反应 Marriage* v4 = new Marriage(); //显示反应 object.Display(v4); return 0; }
程序输出:
clh@clh:~/testcode/设计模式$ g++ visitor.cpp -std=c++11 -g clh@clh:~/testcode/设计模式$ ./a.out 男人成功时,背后多半有个伟大的女人。 女人成功时,背后多半有个不成功的男人。 男人失败时,闷头喝酒,谁也不用劝。 女人失败时,两眼泪汪汪,谁也劝不了。 男人恋爱时,不懂也要装懂。 女人恋爱时,懂也要装不懂。 男人结婚时,感慨道:恋爱游戏终结时,‘有妻徒刑’遥无期。 女人结婚时,欣慰曰:爱情长跑路漫漫,婚姻保险保平安。
以下内容摘抄自《设计模式》:
访问者模式适用性:
1.一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
2.需要对一个对象结构中的对象进行很多不同且不相关的操作,而你想避免让这些操作“污染”这些对象的类,visitor使得你可以将相关的操作集中起来定义在一个类中。
3.定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,者可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作比较好。
访问者模式的优点:
1.访问者模式易于增加新的操作 访问者使得增加以来于复杂对象结构的构建的操作变得更容易了。仅需增加一个新的访问者即可在一个对象结构上定义一个新的操作。相反,如果每个功能都分散在多个类智商的话,定义新的操作时必须修改每一个类。
2.访问者集中相关的操作而分离无关的操作 相关的行为不是分布在定义该对象结构的各个类上,而是集中在一个访问者中。无关行为却被分别放在它们各自的访问者子类中。这就简化了这些元素的类,也简化了在这些访问者中定义的算法。所有与它的算法相关的数据结构都可以被隐藏在访问者中。
3.访问限制少 可以访问不具有相同父类的对象。可以对一个visitor接口增加任何类型的对象,它们不必继承相同的父类。
4.积累状态 当访问者访问对象结构中的每一个元素时,它可能会积累状态。如果没有访问者,这一状态将作为额外的参数传递给进行遍历的操作,或者定义为全局变量。
访问者模式的缺点:
1.增加新的ConcreteElement类很困难 visitor模式使得难以增加新的Element的子类。每添加一个新的ConcreteElement都要visitor中添加一个新的抽象操作,并在每一个ConcretVisitor类中实现相应操作。
2.破坏封装 访问者方法嘉定ConcreteElement接口的功能足够强,足以让访问者进行它们的工作。结果时,该模式常常迫使你提供访问元素内部状态的公共操作,这可能会破坏它们的封装性。
转载请注明源地址:http://blog.csdn.net/clh01s
相关文章推荐
- 设计模式(17) 访问者模式(VISITOR) C++实现
- 我所理解的设计模式(C++实现)——访问者模式(Visitor Pattern)
- C++ 设计模式 —— 访问者(Visitor)
- 常见设计模式的解析和实现(C++)之二十-Visitor模式
- 设计模式-创建型 C++版本
- JAVA设计模式(23):行为型-访问者模式(Visitor)
- 《模式——工程化实现及扩展》(设计模式C# 版)《访问者模式 Visitor》——“自我检验"
- C++设计模式之十九--Visitor访问者模式
- 设计模式系列7-----C++实现访问者模式(Visitor Pattern)
- 学习php设计模式 php实现访问者模式(Visitor)
- C++设计模式之二十三:Visitor(访问者模式)
- 设计模式(十三)-访问者模式(Visitor Pattern)——访问数据结构并处理数据
- [GoF设计模式]Composite模式和Visitor模式的C++实现
- 程序基础设计模式的解析和实现(C++)之二十-Visitor模式
- 设计模式(23)-访问者模式(Visitor)
- 我所理解的设计模式(C++实现)——访问者模式(Visitor Pattern)
- JAVA设计模式—访问者模式(Visitor)
- 设计模式(23)-行为型-访问者模式(Visitor)
- 设计模式-行为型-访问者模式(Visitor)
- 浅谈JAVA设计模式之——访问者模式(Visitor)