在软件开发中,经常需要用到多态,继承等机制,下面是很常见的一段代码

class Brand
{
public:virtual void productShoe() = 0;
}class Nike : public Brand
{
public:virtual void productShoe(){//createAj1();}
};class Adidas : public Brand
{
public:virtual void productShoe(){//createYeezy();}
};

基类品牌有一个生产鞋子的方法,子类继承并重写(override)。这种类的层次结构中常常会需要增加新的行为,比如我们需要生产衣服,我们一般会这么改。

class Brand
{
public:virtual void productShoe() = 0;virtual void productClothes() = 0;
}class Nike : public Brand
{
public:virtual void productShoe() override{//createAj1();}virtual void productClothes(){//createNSW();}
};class Adidas : public Brand
{
public:virtual void productShoe(){//createYeezy();}virtual void productClothes(){//createOriginals();}
};

问题来了,这样改会更改抽象基类,但是抽象应该是稳定的(依赖倒置),并且也不符合开放封闭原则(对修改封闭)。

这样,我们的访问者模式就应运而出了!

(当然,在这里我们可以默认这整个类的层次结构是不会改变的,也就是就这么几个子类)

访问者模式是为了解决行为变化的,和命令者模式(command)一起归为行为变化模式。

我们可以将代码用访问者模式重构成如下代码

class Visitor;class Brand
{
public:virtual void accept(Visitor& visitor) = 0;
}class Nike : public Brand
{
public:virtual void accept(Visitor& visitor){visitor.visitNike(*this);}
};class Adidas : public Brand
{
public:virtual void accept(Visitor& visitor){visitor.visitAdidas(*this);}
};class Visitor
{
public:virtual void visitNike(Nike& nike) = 0;virtual void visitAdidas(Adidas& adidas) = 0;
};class ShoeVisitor : public Visitor
{
public:virtual void visitNike(Nike& nike){//nike.createAj();};virtual void visitAdidas(Adidas& adidas){//adidas.createYeezy();}
};

这样,我们调用的时候只需这样:

Adidas adidas;
ShoeVisitor visitor;
adidas.accept(visitor);    //double dispatch

注意,注释的地方的double dispatch的含义是两次多态辨析,意思是这里使用了两次多态调用。

首先accept方法是继承自基类Brand,其次accept里面的visitAdidas的方法也是来自原基类Visitor的虚函数,这又是一次多态。

这样,我们的功能(行为)就可以都写在visitNike里面,而不必破坏原有的类结构。

缺点:

我们从上面代码可以看出,基类Visitor是一个抽象基类,抽象就应该是稳定的,而基类Visitor中的两个方法都是依赖于Brand的两个子类Nike和Adidas,这就说明这个体系中,Brand和Brand的两个子类也应该是稳定的,然而这个条件很难达到。

ps:一般这个模式都是运用在一种固定的类结构中(比如树形结构中),对不同的对象(不同类型的树节点)进行不同的操作(可以是处理数据节点,也可以是遍历父节点),这里子类的类型必须要是稳定的(树节点的类型是稳定的)。

设计模式(二) 访问者模式 Vistor相关推荐

  1. 设计模式:访问者模式-vistor

    表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作 访问者模式的优点 1.符合单一职责原则:凡是适用访问者模式的场景中,元素类中需要封装在访问者中 ...

  2. 访问者模式的java语言_Java 设计模式系列(二三)访问者模式(Vistor)

    Java 设计模式系列(二三)访问者模式(Vistor) 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以 ...

  3. 北风设计模式课程---访问者模式(Visitor)

    北风设计模式课程---访问者模式(Visitor) 一.总结 一句话总结: 设计模式是日常问题的经验总结方案,所以学好设计模式对日常出现的问题可以有很好的解决. 访问者设计模式有点神似 抽象工厂模式, ...

  4. Java设计模式(访问者模式-迭代器模式-观察者模式-中介者模式)

    Java设计模式Ⅶ 1.访问者模式 1.1 访问者模式概述 1.2 代码理解 2.迭代器模式 2.1 迭代器模式概述 2.2 代码理解 3.观察者模式 3.1 观察者模式概述 3.2 代码理解 4.中 ...

  5. 大话设计模式(二)代理模式

    大话设计模式(二)代理模式 前言 代理模式(Proxy Pattern)是GoF 23种Java常用设计模式之一.代理模式的定义:Provide a surrogate or placeholder ...

  6. java的string访问某个元素_C#深究.net常用的23种设计模式之访问者模式(Vistor Pattern)...

    一.引言 在上一篇博文中分享了责任链模式,责任链模式主要应用在系统中的某些功能需要多个对象参与才能完成的场景.在这篇博文中,我将为大家分享我对访问者模式的理解. 二.访问者模式介绍 2.1 访问者模式 ...

  7. C#设计模式(22)——访问者模式(Vistor Pattern)

    一.引言 在上一篇博文中分享了责任链模式,责任链模式主要应用在系统中的某些功能需要多个对象参与才能完成的场景.在这篇博文中,我将为大家分享我对访问者模式的理解. 二.访问者模式介绍 2.1 访问者模式 ...

  8. 设计模式:访问者模式(Vistor)

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  9. 设计模式之访问者模式(Vistor)

    访问者模式定义 访问者模式是封装一些施加于某种数据结构之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变.访问者模式适用于数据结构相对稳定的系统, 它把数据结构和作用于数据结构 ...

最新文章

  1. 小团队如何玩转物联网开发?
  2. Java中的低级错误
  3. 047_Unicode对照表十三
  4. python判断字符是否是字典的键_Python3基础 dict in/not in 查询一个字符是否指定字典的键或者值...
  5. url中参数以及callback后面的串
  6. matlab中.P文件的使用说明
  7. 活动目录网域中禁用移动存储(U盘)
  8. vue多选框点击其中一个控制div隐藏_Vue 零碎知识点
  9. Gartner公布2017年全球云存储魔力象限:阿里云跻身四强
  10. c语言第六章谭浩强ppt,谭浩强C语言课件第6章.ppt
  11. Wordpress淘宝客专用链接跳转插件Pretty Link Lite
  12. raw socket 编程实例
  13. GNS3+JunOS
  14. 【学习笔记】软件测试-版本迭代总结
  15. 伪随机数产生原理及用法
  16. [渝粤教育] 西南科技大学 资源与环境概论 在线考试复习资料
  17. 【读书笔记】《中央帝国的财政密码》
  18. grafana图形化数据展示软件介绍
  19. HDU 6078 Wavel Sequence
  20. 什么是NaN,NaN==NaN?

热门文章

  1. 2020年杭州社保个人最低交多少
  2. [动态系统的建模与分析]15_伯德图,bode图,为什么是20logM?分贝又是什么?
  3. python爬虫中遇到“\xb5”、“xa0”等字符时报错编码错误的处理方式
  4. ad板子挖孔_用AD软件画孔的注意了!
  5. Kernel panic - not syncing: Attempted to kill init
  6. HBuilderXHBuilder连接雷电模拟器“未检测到手机或模拟器” ---- 问题解决
  7. 将ceph与calamari相连(connect ceph servers to calamari)
  8. IBM-kmeans-坏盘预测
  9. 求集合中最大值、最小值、和
  10. mrtg流量图不更新了是怎么回事,谁有mrtg的安装及配置文档啊,求!!!