设计模式模式游客(Visitor)摘录
23种子GOF设计模式一般分为三类:创建模式、结构模型、行为模式。
结构型模式涉及到怎样组合类和对象以获得更大的结构。结构型类模式採用继承机制来组合接口或实现。
行为对象模式使用对象复合而不是继承。一些行为对象模式描写叙述了一组对等的对象怎样相互协作以完毕当中任一个对象都无法单独完毕的任务。
Factory Method:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。
Abstract Factory:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们详细的类。
Singleton:保证一个类仅有一个实例,并提供一个訪问它的全局訪问点。
Builder:将一个复杂对象的构建与它的表示分离,使得相同的构建过程能够创建不同的表示。
Prototype:用原型实例指定创建对象的种类,而且通过拷贝这个原型来创建新的对象。
Bridge:将抽象部分与它的实现部分分离,使它们都能够独立地变化。
Adapter:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类能够一起工作。
Decorator:动态地给一个对象加入一些额外的职责。就扩展功能而言, Decorator模式比生成子类方式更为灵活。
Composite:将对象组合成树形结构以表示“部分-总体”的层次结构。Composite使得客户对单个对象和复合对象的使用具有一致性。
Flyweight:运用共享技术有效地支持大量细粒度的对象。
Facade:为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口。这个接口使得这一子系统更加easy使用。
Template Method:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类能够不改变一个算法的结构就可以重定义该算法的某些特定步骤。
Strategy:定义一系列的算法,把它们一个个封装起来, 而且使它们可相互替换。
State:同意一个对象在其内部状态改变时改变它的行为。对象看起来似乎改动了它所属的类。
Observer:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,全部依赖于它的对象都得到通知并自己主动刷新。
Memento:在不破坏封装性的前提下。捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。
Mediator:用一个中介对象来封装一系列的对象交互。中介者使各对象不须要显式地相互引用。从而使其耦合松散,而且能够独立地改变它们之间的交互。
Command:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行參数化。对请求排队或记录请求日志。以及支持可取消的操作。
Visitor:表示一个作用于某对象结构中的各元素的操作。它使你能够在不改变各元素的类的前提下定义作用于这些元素的新操作。
Chain of Responsibility:为解除请求的发送者和接收者之间耦合。而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求。直到有一个对象处理它。
Iterator:提供一种方法顺序訪问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
Interpreter:给定一个语言, 定义它的文法的一种表示。并定义一个解释器, 该解释器使用该表示来解释语言中的句子。
Visitor:(1)、意图: 表示一个作用于某对象结构中的各元素的操作。
它使你能够在不改变各元素的类的前提下定义作用于这些元素的新操作。
Visitor使得你能够将相关的操作集中起来定义在一个类中。
当该对象结构被非常多应用共享时,用Visitor模式让每个应用仅包含须要用到的操作。C、定义对象结构的类非常少改变,但常常须要在此结构上定义新的操作。
改变对象结构类须要重定义对全部訪问者的接口。这可能须要非常大的代价。
假设对象结构类常常改变,那么可能还是在这些类中定义这些操作较好。
(3)、优缺点:A、訪问者模式使得易于添加新的操作:訪问者使得添加依赖于复杂对象结构的构件的操作变得easy了。
仅需添加一个新的訪问者就可以在一个对象结构上定义一个新的操作。
这就既简化了这些元素的类,也简化了在这些訪问者中定义的算法。
在这样的情况下,直接在构成该结构的类中定义这些操作可能更easy一些。假设Element类层次是稳定的。而你不断地添加操作或改动算法,訪问者模式能够帮助你管理这些改动。
D、通过类层次进行訪问:一个迭代器能够通过调用节点对象的特定操作来遍历整个对象结构。同一时候訪问这些对象。
E、累积状态:当訪问者訪问对象结构中的每个元素时,它可能会累积状态。
(4)、相关模式:A、Composite:訪问者能够用于对一个由Composite模式定义的对象结构进行操作。
长处:新添加操作非常easy。由于添加新操作就相当于添加一个訪问者,訪问者模式将有关的行为集中到一个訪问者对象中。
(6)、Visitor模式在不去破坏类的前提下,为类提供添加新的操作。
Visitor模式的关键是双分派(Double-Dispatch)的技术。
可是不管哪种情况,特别是后者都将破坏封装性原则(实际上就是C++的friend机制得到了非常多的面向对象专家的诟病)。
不管哪种方式都给扩展新的Element子类带来了困难。RTTI给接口带来了简单一致性,可是付出的代价是时间(RTTI的实现)和代码的Hard编码(要进行强制转换)。
#include <iostream>
#include <string>
#include <vector>using namespace std;class Man;
class Woman;//行为
class Action
{
public:virtual void GetManConclusion(Man* concreteElementA) = 0;virtual void GetWomanConclusion(Woman* concreteElementB) = 0;
};//成功
class Success : public Action
{
public:virtual void GetManConclusion(Man* concreteElementA){cout<<"男人成功时。背后有个伟大的女人"<<endl;}virtual void GetWomanConclusion(Woman* concreteElementB){cout<<"女人成功时,背后有个无用的男人"<<endl;}
};//失败
class Failure : public Action
{
public:virtual void GetManConclusion(Man* concreteElementA){cout<<"男人失败时。背后有个伟大的女人"<<endl;}virtual void GetWomanConclusion(Woman* concreteElementB){cout<<"女人失败时。背后有个无用的男人"<<endl;}
};//抽象人类
class Person
{
public:virtual void Accept(Action* visitor) = 0;
};//男人
class Man : public Person
{
public:virtual void Accept(Action* visitor){visitor->GetManConclusion(this);}
};//女人
class Woman : public Person
{
public:virtual void Accept(Action* visitor){visitor->GetWomanConclusion(this);}
};//对象结构类
class ObjectStructure
{
private:vector<Person*> m_personList;
public:void Add(Person* p){m_personList.push_back(p);}void Display(Action* a){vector<Person*>::iterator p = m_personList.begin();while (p != m_personList.end()) {(*p)->Accept(a);p ++;}}
};//client
int main()
{ObjectStructure* os = new ObjectStructure();os->Add(new Man());os->Add(new Woman());Success* success = new Success();os->Display(success);Failure* fl = new Failure();os->Display(fl);/*result男人成功时,背后有个伟大的女人女人成功时,背后有个无用的男人男人失败时,背后有个伟大的女人女人失败时。背后有个无用的男人*/return 0;
}
Visitor.h:
#ifndef _VISITOR_H_
#define _VISITOR_H_class ConcreteElementA;
class ConcreteElementB;
class Element;class Visitor
{
public:virtual ~Visitor();virtual void VisitConcreteElementA(Element* elm) = 0;virtual void VisitConcreteElementB(Element* elm) = 0;
protected:Visitor();
private:
};class ConcreteVisitorA : public Visitor
{
public:ConcreteVisitorA();virtual ~ConcreteVisitorA();virtual void VisitConcreteElementA(Element* elm);virtual void VisitConcreteElementB(Element* elm);
protected:
private:
};class ConcreteVisitorB : public Visitor
{
public:ConcreteVisitorB();virtual ~ConcreteVisitorB();virtual void VisitConcreteElementA(Element* elm);virtual void VisitConcreteElementB(Element* elm);
protected:
private:
};#endif//~_VISITOR_H_
Visitor.cpp:
#include "Visitor.h"
#include "Element.h"
#include <iostream>using namespace std;Visitor::Visitor()
{}Visitor::~Visitor()
{}ConcreteVisitorA::ConcreteVisitorA()
{}ConcreteVisitorA::~ConcreteVisitorA()
{}void ConcreteVisitorA::VisitConcreteElementA(Element* elm)
{cout<<"I will visit ConcreteElementA ..."<<endl;
}void ConcreteVisitorA::VisitConcreteElementB(Element* elm)
{cout<<"I will visit ConcreteElementB ..."<<endl;
}ConcreteVisitorB::ConcreteVisitorB()
{}ConcreteVisitorB::~ConcreteVisitorB()
{}void ConcreteVisitorB::VisitConcreteElementA(Element* elm)
{cout<<"I will visit ConcreteElementA ..."<<endl;
}void ConcreteVisitorB::VisitConcreteElementB(Element* elm)
{cout<<"I will visit ConcreteElementB ..."<<endl;
}
Element.h:
#ifndef _ELEMENT_H_
#define _ELEMENT_H_class Visitor;class Element
{
public:virtual ~Element();virtual void Accept(Visitor* vis) = 0;
protected:Element();
private:
};class ConcreteElementA : public Element
{
public:ConcreteElementA();~ConcreteElementA();void Accept(Visitor* vis);
protected:
private:
};class ConcreteElementB : public Element
{
public:ConcreteElementB();~ConcreteElementB();void Accept(Visitor* vis);
protected:
private:
};#endif//~_ELEMENT_H_
Element.cpp:
#include "Element.h"
#include "Visitor.h"
#include <iostream>using namespace std;Element::Element()
{}Element::~Element()
{}void Element::Accept(Visitor* vis)
{}ConcreteElementA::ConcreteElementA()
{}ConcreteElementA::~ConcreteElementA()
{}void ConcreteElementA::Accept(Visitor* vis)
{vis->VisitConcreteElementA(this);cout<<"visiting ConcreteElementA ..."<<endl;
}ConcreteElementB::ConcreteElementB()
{}ConcreteElementB::~ConcreteElementB()
{}void ConcreteElementB::Accept(Visitor* vis)
{cout<<"visiting ConcreteElementB ..."<<endl;vis->VisitConcreteElementB(this);
}
main.cpp:
#include "Element.h"
#include "Visitor.h"
#include <iostream>using namespace std;int main()
{Visitor* vis = new ConcreteVisitorA();Element* elm = new ConcreteElementA();elm->Accept(vis);/*resultI will visit ConcreteElementA ...visiting ConcreteElementA ...*/return 0;
}
訪问者模式结构图:
參考文献:
1、《大话设计模式C++》
2、《设计模式精解----GoF23分析设计模式》
3、《设计模式----可重用的对象取向软件基础》
版权声明:本文博客原创文章,博客,未经同意,不得转载。
设计模式模式游客(Visitor)摘录相关推荐
- 设计模式之访问者模式(Visitor)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 设计模式--访问者模式(Visitor)
访问者模式(Visitor) 在现实生活中,有些集合对象中存在多种不同的元素,且每种元素也存在多种不同的访问者和处理方式.例如,公园中存在多个景点,也存在多个游客,不同的游客对同一个景点的评价可能不同 ...
- 设计模式之十五:訪问者模式(Visitor Pattern)
訪问者模式(Visitor Pattern)是GoF提出的23种设计模式中的一种,属于行为模式. 据<大话设计模式>中说算是最复杂也是最难以理解的一种模式了. 定义(源于GoF<De ...
- 研磨设计模式 之 访问者模式(Visitor)2——跟着cc学设计系列
25.2 解决方案 25.2.1 访问者模式来解决 用来解决上述问题的一个合理的解决方案,就是使用访问者模式.那么什么是访问者模式呢? (1)访问者模式定义 (2)应用访问者模式来解决的思路 仔细 ...
- 北风设计模式课程---访问者模式(Visitor)
北风设计模式课程---访问者模式(Visitor) 一.总结 一句话总结: 设计模式是日常问题的经验总结方案,所以学好设计模式对日常出现的问题可以有很好的解决. 访问者设计模式有点神似 抽象工厂模式, ...
- 设计模式学习之访问者模式(Visitor,行为型模式)(21)
参考:https://www.cnblogs.com/edisonchou/p/7247990.html 在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根 ...
- Net设计模式实例之访问者模式(Visitor Pattern)
一.访问者模式简介(Brief Introduction) 表示一个作用于某对象结构中的元素操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作,它把数据结构和作用于结构上的操作之间的耦 ...
- 设计模式之模板方法模式(Template Method)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 设计模式之建造者模式(生成器模式、Builder)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式包括:1.FactoryMethod(工厂方法模式):2.Abstract Factory(抽象工厂模式):3.Sin ...
最新文章
- YOLOv3 训练的各种config文件以及weights文件。
- Hadoop For Windows
- 排球计分程序(三)—— 模型类的设计与实现
- 如何采用python语言绘制一条_如何使用matplotlib绘制一条线?
- 单进程服务器(python版)
- 将String 转换为byte[]数组
- 新手redis集群搭建
- BZOJ4571: [Scoi2016]美味【主席树】【贪心】
- 阿里云云计算 9 弹性裸金属服务器(神龙)
- Contrastive Loss(对比损失)
- Sencha Architect4.0破解教程
- java split保留分隔_String split如何保留分隔符
- 福利:阿里云免费试用劵
- 计算机大学四年该如何努力学习?
- 关系型数据库事务处理ACID
- mybatis 传入参数及其 foreach collection的三种用法
- nutanix方案建议书
- java pdf 富文本_java根据富文本生成pdf文件
- 30天全网2W粉,感谢坚持!
- 【考研数据】二.2021年BJTU计算机学院考研录取数据分析
热门文章
- Excel访问局域网中OLAP方案
- android 表示空字符串,Android Logcat获取空字符串时非常奇怪的行为
- Python字符串居然可以这样玩 到底怎么做到的 年薪50w程序员揭晓
- mysql 2003错误 10055_MYSQL无法连接 提示10055错误的解决方法
- java数列求和_java中关于数列求和的计算方法
- python数字类型转换函数_Python的数据类型转换函数
- Jenkins 在 Kubernetes 上的实践
- 单片机基础课程有哪些?
- New Year Tree(dfs序+线段树+二进制)
- 图论 ---- F. Useful Edges(不等式移项优化预处理 + 路径和简单路径的区别 + 最短路)