访问者模式

  • 一、概述
    • 二、结构
      • 三、实例
      • 四、优缺点
      • 五、适用场景

一、概述

描述:顾客在超超市购买商品时,如苹果、图书等将放在购物车中,然后到收银员付款。在购物过程中,顾客需要对这些商品访问,以便确保这些质量,之后收银员计算价格时也需访问购物车中的商品。
购物车作为ObjectStructure(对象结构)用于存放各种商品,而顾客和收银员作为访问这些商品的访问者,们需要对商品进行检查和计价。不同类型的商品其访问形式也可能不同,如苹果需要过秤之后再计价,而图书不需要。

定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。适用于数据结构稳定的系统,它把数据结构和作用于数据结构上的操作分离开,使得操作集合。

二、结构

  1. 访问者(Visitor)接口声明了一系列以对象结构的具体元素为参数的访问者方法。如果编程语言支持重载,这些方法的名称可以是相同的,但是其参数一定是不同的。
  2. 具体访问者(Concrete Visitor)会为不同的具体元素类实现相同行为的几个不同版本。
  3. 元素(Element) 接口声明了一个方法来“接收” 访问者。该方法必须有一个参数被声明为访问者接口类型。
  4. 具体元素(Concrete Element)必须实现接收方法。 该方法的目的是根据当前元素类将其调用重定向到相应访问者的方法。请注意,即使元素基类实现了该方法,所有子类都必须对其进行重写并调用访问者对象中的合适方法。
  5. 对象结构(ObjectStructure): 能枚举它的元素。可以提供一个高层的接口以允许该访问者访问它的元素。可以是一个复合或是一个集合,如一个列表或一个无序集合。

三、实例

#include<iostream>
#include<string>
#include<list>
using namespace std;
class Apple;
class Book;// 抽象访问者作为接口
class Vistor {protected:string name_;public:void set_name(string name) {name_ = name;}virtual void visit(Apple* apple) = 0;virtual void visit(Book* book) = 0;
};// 具体访问者类: 顾客
class Customer : public Vistor {public:void visit(Apple* apple) {cout << "顾客" << name_ << "挑选苹果。" << endl;}void visit(Book* book) {cout << "顾客" << name_ << "买书。" <<endl;}
};// 具体访问者类: 收银员
class Saler : public Vistor {public:void visit(Apple* apple) {cout << "收银员" << name_ << "给苹果过称, 然后计算价格。" << endl;}void visit(Book* book) {cout << "收银员" << name_ << "计算书的价格。" << endl;}
};// 抽象元素类
class Product {public:virtual void accept(Vistor* vistor) = 0;
};// 具体产品类: 苹果
class Apple :public Product {public://方便调用Vistor中visit函数void accept(Vistor* vistor) override {vistor->visit(this);}
};// 具体产品类: 书籍
class Book :public Product {public:void accept(Vistor* vistor)override {vistor->visit(this);}
};// 购物车
class ShoppingCart {private:list<Product*> prd_list_;
public:void accept(Vistor* vistor) {for (auto prd : prd_list_) {prd->accept(vistor);}}void addProduct(Product* product) {prd_list_.push_back(product);}void removePeoduct(Product* product) {prd_list_.push_back(product);}};int main()
{Book book;Apple apple;ShoppingCart basket;basket.addProduct(&book);basket.addProduct(&apple);Customer customer;customer.set_name("小张");basket.accept(&customer);Saler saler;saler.set_name("小杨");basket.accept(&saler);return 0;}

四、优缺点

优点:

  1. 使得增加新的访问操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易。
  2. 将有关元素对象的访问行为集中到一个访问者对象中,而不是分散到一个个的元素类中。
  3. 访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。
  4. 让用户能够在不修改现有类层次结构的情况下,定义该类层次结构的操作。

缺点:

  1. 增加新的元素类很困难。在访问者模式中,每增加一个新的元素类都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作,违背了“开闭原则”的要求。
  2. 破坏封装。访问者模式要求访问者对象访问并调用每一个元素对象的操作,这意味着元素对象有时候必须暴露一些自己的内部操作和内部状态,否则无法供访问者访问。

五、适用场景

  1. 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
  2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。
  3. 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。

Vistor(访问者模式)行为型相关推荐

  1. 设计模式之 Vistor 访问者模式:Swift 实现

    Vistor Mode: 访问者模式 访问者在获得权限的之后,可以访问被访者的各项内容,同时,不能影响到被访者的属性,这样才是一个文明的访问者. Visitor mode can isolate th ...

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

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

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

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

  4. 设计模式-访问者模式

    一.访问者模式(行为型模式) 1.定义 访问者模式(Vistor Pattern)是一种将数据结构和数据操作分离的设计模式.是指封装一些作用于某种数据结构中的各种元素的操作,它可以在不改变数据结构的前 ...

  5. [设计模式-行为型]访问者模式(Vistor)

    一句话 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 概括 解析 情人节到了,要给每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对 ...

  6. Java设计模式之行为型:访问者模式

    背景: 去医院看病时,医生会给你一个处方单要你去拿药,拿药我们可以分为两步走: (1)去柜台交钱,划价人员会根据处方单上的药进行划价,交钱. (2)去药房拿药,药房工作者同样根据处方单给你相对应的药. ...

  7. C#设计模式之二十一访问者模式(Visitor Pattern)【行为型】

    一.引言 今天我们开始讲"行为型"设计模式的第九个模式,该模式是[访问者模式],英文名称是:Visitor Pattern.如果按老规矩,先从名称上来看看这个模式,我根本不能获得任 ...

  8. 行为型:设计模式之访问者模式(二十三)

    想必大家都去过医院,虽然没有人喜欢去医院(爱岗敬业的医务工作人员除外,).在医生开具处方单(药单)后,很多医院都存在如下处理流程:划价人员拿到处方单之后根据药品名称和数量计算总价,药房工作人员根据药品 ...

  9. 行为型模式:访问者模式

    前方高能:<一故事一设计模式>PDF 电子书已经上线,关注公众号即可获取. 文章首发: 行为型模式:访问者模式 十一大行为型模式之十一:访问者模式. 简介 姓名 :访问者模式 英文名 :V ...

最新文章

  1. mysql表情符号变为_mysql Emoji表情字符集转换
  2. 深度学习之好的博客文章
  3. OpenKruise :SidecarSet 助力 Mesh 容器热升级
  4. sftp shell 批量上传文件_shell脚本进行sftp、ftp文件批量上传与下载
  5. Vue.js-Day02-AM【Vue表单、核心指令(单选框、密码框、多行文本框、单选、多选、勾选、下拉列表)、组件汇总案例、ToDoList案例、计算属性(computed)、watch监听】
  6. Flink示例——Flink-CDC
  7. 学完计算机还是不懂,如果看了这篇文章你还不懂傅里叶变换,那就过来掐死我吧...
  8. 【干货】规模化敏捷DevOps四大实践之持续探索CE(中英对照版)
  9. 如何基于tomcat构建web站点
  10. [BZOJ 3531][Sdoi2014]旅行(树链剖分+线段树)
  11. Github 源码阅读神器:Octotree
  12. 白盒测试实验报告模板
  13. 2012-2013考研英语词汇
  14. 上升时间测量与示波器带宽
  15. nodejs todu小damo
  16. Python for Data Analysis v2 | Notes_ Chapter_5 pandas 入门
  17. ipv6被拒的解决方法
  18. 那些令人发燥的JAVA虚引用
  19. error LNK1120: 1 个无法解析的外部命令(详细小问题解释)
  20. shentou mianshiti

热门文章

  1. 2021年煤矿井下爆破模拟试题及煤矿井下爆破考试试题
  2. 寻觅那款你心仪的国际象棋app
  3. Linux文件系统管理-常用命令df\du\fsck\dumpe2fs
  4. java dms_奥点云-DMS Java API 文档
  5. 香港伦敦金交易平台排行榜(2022最新版)
  6. Day 15 正则表达式
  7. 虚拟机安装CentOs系统
  8. 移动磁盘显示盘符但无法打开,提示格式化
  9. win10 运行debussy不能打开波形窗口问题
  10. 描述计算机内的存储单位及换算关系,计算机存储单位换算