访问者模式(Vistor Pattern)

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/431 访问。

访问者模式属于行为型模式,表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

结构对象是使用访问者模式必备条件,而且这个结构对象必须存在遍历自身各个对象的方法。

角色:

1、抽象访问者(Visitor)

为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它;

2、具体访问者(Concrete Visitor)

实现Visitor声明的接口;

3、抽象元素(Element)

定义一个接受访问操作,它以一个访问者(Visitor)作为参数;

4、具体元素(Concrete Element )

实现了抽象元素所定义的接受操作接口;

5、结构对象(Object Structure)

可以提供一个高层接口以允许访问者访问它的元素。

示例:

命名空间VistorPattern中包含Student学生基类充当抽象元素,它的3个实现类Kris、Cherry和Harling分别是我的儿子、女儿和侄女的英文名,它们充当具体元素角色。ITeacher接口充当抽象访问者,而Teacher类充当具体访问者。花名册类Roster充当结构对象。本案例尝试使用老师根据花名册来进行家访这样的场景来讲述访问者模式的使用方法。

namespace VistorPattern
public abstract class Student {

	public string Name { get; protected set; }

	public Student(string name) {
Name = name;
} public abstract void Accept(ITeacher teacher); }

学生基类Student,代表抽象元素。

public class Kris : Student {

	public Kris(string name) : base(name) {

	}

	public override void Accept(ITeacher teacher) {
teacher.Visit(this);
} }

Kris类,代表某一具体学生。

public class Cherry : Student {

	public Cherry(string name) : base(name) {

	}

	public override void Accept(ITeacher teacher) {
teacher.Visit(this);
} }

Cherry类,代表某一具体学生。

public class Harling : Student {

	public Harling(string name) : base(name) {

	}

	public override void Accept(ITeacher teacher) {
teacher.Visit(this);
} }

Harling类,代表某一具体学生。

public interface ITeacher {

	void Visit(Student student);

}

ITeacher接口,代表抽象访问者。

public class Teacher : ITeacher {

	private string _name = null;

	public Teacher(string name) {
_name = name;
} public void Visit(Student student) {
Console.WriteLine($"Mr.{_name} is going to visit {student.Name}'s home. ");
} }

Teacher类,代表具体访问者。

public class Roster {

	public List<Student> Students { get; private set; }

	public Roster() {
Students = new List<Student> {
new Cherry("Cherry"),
new Kris("Kris"),
new Harling("Harling")
};
} }

Roster类,代表花名册,充当结构对象,老师根据这个对象来进行家访。

public class Program {

	public static void Main(string[] args) {
Roster roster = new Roster();
foreach(var student in roster.Students) {
student.Accept(new Teacher("Tony"));
} Console.Read();
} }

以上是调用方的代码,以下是这个案例的输出结果:

Mr.Tony is going to visit Cherry's home.
Mr.Tony is going to visit Kris's home.
Mr.Tony is going to visit Harling's home.

优点:

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/431 访问。

1、符合单一职责原则,凡是适用访问者模式的场景中,元素类中需要封装在访问者中的操作必定是与元素类本身关系不大且是易变的操作,使用访问者模式一方面符合单一职责原则,另一方面,因为被封装的操作通常来说都是易变的,所以当发生变化时,就可以在不改变元素类本身的前提下,实现对变化部分的扩展;

2、扩展性良好,元素类可以通过接受不同的访问者来实现对不同操作的扩展。

缺点:

1、增加新的元素类变得困难,每增加一个新的元素意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中添加相应的具体操作。

使用场景:

1、一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作;

2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor模式使得你可以将相关的操作集中起来 定义在一个类中;

3、当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作;

4、定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

C#设计模式之23-访问者模式的更多相关文章

  1. 重学 Java 设计模式:实战访问者模式「模拟家长与校长,对学生和老师的不同视角信息的访问场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 能力,是你前行的最大保障 年龄会不断的增长,但是什么才能让你不 ...

  2. 设计模式 ( 二十 ) 访问者模式Visitor(对象行为型)

    设计模式 ( 二十 ) 访问者模式Visitor(对象行为型) 1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象, ...

  3. [设计模式] 23 访问者模式 visitor Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问 ...

  4. Java进阶篇设计模式之十 ---- 访问者模式和中介者模式

    前言 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator Pattern).本篇则来学习下行为型模式的两个模式,访问者模式(Visito ...

  5. 设计模式学习之访问者模式(Visitor,行为型模式)(21)

    参考:https://www.cnblogs.com/edisonchou/p/7247990.html 在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根 ...

  6. Java设计模式之十 ---- 访问者模式和中介者模式

    前言 2018年已经过去,新的一年工作已经开始,继续总结和学习Java设计模式. 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator P ...

  7. 《JAVA设计模式》之访问者模式(Visitor)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要 ...

  8. C#设计模式系列:访问者模式(Visitor)

    1.访问者模式简介 1.1>.定义 作用于某个对象群中各个对象的操作,可以使在不改变对象本身的情况下,定义作用于对象的新操作. 1.2>.使用频率   低 2.访问者模式结构 2.1> ...

  9. 设计模式のVisitorPattern(访问者模式)----行为模式

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

  10. java设计模式-----24、访问者模式

    概念: Visitor模式也叫访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作. 访问者模式的应用示例 比如有一个公园,有一到多个不同 ...

随机推荐

  1. OSCP Learning Notes - WebApp Exploitation(4)

    Local File Inclusion[LFI] Target Pentester Lab: Download from the following website: https://www.vul ...

  2. Python Ethical Hacking - Malware Analysis(4)

    DOWNLOAD_FILE Download files on a system. Once packaged properly will work on all operating systems. ...

  3. msf stagers开发不完全指北(四): msf 中使用域前置技术隐藏流量

    msf 中使用域前置技术隐藏流量 前几篇都是说了下如何采用不同的语言开发 reverse_tcp 第二阶段,接下来将慢慢分析 reverse_http,这篇文章并不会围绕 stagers 进行讲解,这 ...

  4. 入门大数据---Hive计算引擎Tez简介和使用

    一.前言 Hive默认计算引擎时MR,为了提高计算速度,我们可以改为Tez引擎.至于为什么提高了计算速度,可以参考下图: 用Hive直接编写MR程序,假设有四个有依赖关系的MR作业,上图中,绿色是Re ...

  5. echarts 踩坑 : id必须不同

    我们可能用react前端框架开发项目. 也就是组件化开发. 一个页面里可能有很多组件. 而echarts是寻找特定ID的DOM去渲染的. 也就是说,如果整个页面.包括所有页面组件,有id相同的DOM, ...

  6. Python的telnetlib模块使用

    telnetlib模块的常用接口 telnetlib.Telnet(host, port, timeout) # 登录 write() # 输入命令 read_until(match) # 读出响应, ...

  7. java代码之美(17) ---Java8 LocalDateTime

    Java8 LocalDateTime 在java8之前我们在处理时间的时候都是用的Date,但它其实有很明显的缺点. 1.我们也会对日期做一些操作,比如加几天.加几分,当月的最后一天等等.有些计算实 ...

  8. UVA1104 芯片难题 Chips Challenge

    题目链接 题意 网格上放点,有些强制放,有些不能放,有些可以放可以不放.要求: 第 \(i\) 行的点数 = 第 \(i\) 列的点数 每一行每一列的点数不超过总点数的 \(k\) 倍(\(k\) 已 ...

  9. SpringBoot 整合Mybatis + PageHelper 实现分页

    前言: 现在公司大多数都实现了前后端分离,前端使用Vue.React.AngularJS 等框架,不用完全依赖后端.但是如果对于比较小型的项目,没必要前后端分离,而SpringBoot也基本抛弃了Js ...

  10. assemble、compile、make、build和rebuild的关系

    assemble:打包(之前已经编译了源文件)compile.make.build和rebuild都是编译过程:将源代码转换为可执行代码的过程,Java的编译会将java编译为class文件,将非ja ...