访问者模式(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. P3379 最近公共祖先(LCA) 洛谷

    题意简单明了(这就是个模板). 就是让我们找2个节点的公共祖先而已,但我们要讲的做法不是生硬的爆搜,而且直接搜好像过不去…… 这次就讲我往后拖了n多天才开始学了倍增LCA. 嗯,这个题,如果2个节点的 ...

  2. oracle 在物理机上添加磁盘操作

    物理机上添加磁盘操作 注意:1)物理机上添加磁盘操作,不涉及到start_udev的动作.2)磁盘分区的操作,需要谨慎进行,核准无误后再操作. (1)查看磁盘名称命名 # su - grid$ sql ...

  3. vue : 使用stylus less (包括sublime插件支持)

    版本: vue 2.5.2 webpack 3.6.0 先说stylus. 用npm装个包. npm install stylus stylus-loader --save-dev 然后在.vue文件 ...

  4. C++语法小记---函数对象

    函数对象 用于替代函数指针 优势:函数对象内部可以保存状态,而不必使用全局变量或静态局部变量 关键:重载"()"操作符 #include<iostream> #incl ...

  5. Python基础点记录1

    1 变量:一个变量就是一个单词,只有一个单一的值 1 Python里面的数据类型 interage , floats , booleans , String等 2 Python是一个区分大小写的语言 ...

  6. maven项目原型(idea)

    1: internal -> appfuse-basic-jsf (创建一个基于Hibernate,Spring和JSF的Web应用程序的原型) 2: internal -> appfus ...

  7. 毫不留情地揭开 ArrayList 和 LinkedList 之间的神秘面纱

    先看再点赞,给自己一点思考的时间,思考过后请毫不犹豫微信搜索[沉默王二],关注这个靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有技术大佬整理的面试题, ...

  8. Linux切换用户时报错/.bash_profile: Permission denied,命令行(终端提示符)出现-bash-4.2$

    Linux切换用户时报错/.bash_profile: Permission denied,命令行(终端提示符)出现-bash-4.2$ 利用su - 切换用户时,发现有一个用户切时出现如下情况 [r ...

  9. 性能测试 -- docker安装influxdb

    一.前提 1.项目已经部署好 2.docker已经安装好 二.docker安装influxdb 1.下载influxdb镜像:docker pull tutum/influxdb    1)超时报错: ...

  10. 面试题二十二:链表中倒数第k个节点

    方法一:双指针法定义两个指针A.B,A先走k-1步后再一起走,直到A.next==null注意: 1.链表为空 2.链表长度小于k 3.k<=0 当题目是求链表的中间节点时,可以两个指针从开头开 ...