设计模式-行为型-访问者模式

访问者模式(Vistor):

  访问者模式的官方定义是这样的:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。官方的东西总是晦涩难懂的,那么我们现在就来拆解一下:首先"一个作用于某对象结构中的各元素的操作",提到了三个东西:对象结构、元素、操作。我们都学习过数据结构,数据结构中大家对数据的访问一般都是直接访问其地址。在面向对象的设计中,我们一般也是将数据的访问操作放在类的内部,便于访问。这种设计看似没有什么问题,但当我们想要采用不同方式访问数据或对象结构时就必须要对类进行修改,这样就违反了OCP原则。于是大家会想到将数据结构与操作分离开来,当问们需要添加访问操作的时候直接添加新的类,原来的代码不需要做任何改变,这也是后半句提到的"可以在不改变各元素类的前提下定义作用于这些元素的新操作"。

访问者模式的角色:

  

  1)Visitor:接口或抽象类,定义了对每个Element访问的行为,它的参数就是被访问的元素,它的方法个数理论上与元素的个数是一样的,因此,访问者模式要求元素的类型要稳定,如果经常添加、移除元素类,必然会导致频繁地修改visitor接口,如果出现这种情况,则说明不适合使用该模式。

  2)ConcreteVisitor:具体的访问者,它需要给出对每一个元素类访问时所产生的具体行为。

  3)Element:元素接口或抽象类,它定义了一个接受访问者的方法(accept),其意思就是说每一个元素都可以被访问者访问。

  4)ConcreteElement:具体的元素类,它提供接受访问的具体实现,而这个具体实现通常情况下是使用访问者提供的访问该元素类的方法。

  5)ObjectStructure:定义当中所提到的对象结构,对象结构是一个抽象表述,它内部管理了元素集合,并且可以迭代这些元素提供访问者访问。

示例:

  一个目录下面有文件夹和文件,文件夹和文件是具体的元素类。

1 /// <summary>
 2 /// 抽象访问者
 3 /// </summary>
 4 public abstract class Visitor
 5 {
 6     public abstract void visit(File file);
 7
 8     public abstract void visit(Directory directory);
 9 }
10
11 /// <summary>
12 /// 具体的访问者
13 /// </summary>
14 public class ListVisitor : Visitor
15 {
16     public override void visit(File file)
17     {
18         Console.WriteLine($"文件名称{file.GetName()}");
19     }
20
21     public override void visit(Directory directory)
22     {
23         Console.WriteLine($"文件夹名称{directory.GetName()}");
24     }
25 }
26
27 /// <summary>
28 /// 元素抽象类
29 /// </summary>
30 public abstract class Element
31 {
32     public abstract void accept(Visitor visitor);
33 }
34
35 public class Entry : Element
36 {
37     private string name;
38
39     public Entry(string name)
40     {
41         this.name = name;
42     }
43
44     public string GetName()
45     {
46         return this.name;
47     }
48
49     public override void accept(Visitor visitor)
50     {
51         throw new NotImplementedException();
52     }
53 }
54
55 /// <summary>
56 /// 具体的元素类:文件夹
57 /// </summary>
58 public class Directory : Entry
59 {
60     public Directory(string name)
61         : base(name)
62     {
63     }
64
65     public override void accept(Visitor visitor)
66     {
67         visitor.visit(this);
68     }
69 }
70
71 /// <summary>
72 /// 具体的元素类:文件
73 /// </summary>
74 public class File : Entry
75 {
76     public File(string name)
77         : base(name)
78     {
79     }
80
81     public override void accept(Visitor visitor)
82     {
83         visitor.visit(this);
84     }
85 }

  定义好了,数据操作,接下来我们定义数据结构的核心类ObjectStructure。

1 public class ObjectStructure
 2 {
 3     private readonly Visitor visitor;
 4     private List<Element> list = new List<Element>();
 5
 6     public ObjectStructure(Visitor visitor)
 7     {
 8         this.visitor = visitor;
 9     }
10
11     public void Add(Element element)
12     {
13         list.Add(element);
14     }
15
16     public void Show()
17     {
18         foreach (Element element in list)
19         {
20             element.accept(visitor);
21         }
22     }
23 }

  客户端调用。

1 private static void Main(string[] args)
 2 {
 3     ObjectStructure objectStructure = new ObjectStructure(new ListVisitor());
 4     objectStructure.Add(new Directory("我的文件夹"));
 5     objectStructure.Add(new File("C#高级编程.pdf"));
 6     objectStructure.Add(new File("设计模式.pdf"));
 7     objectStructure.Add(new File("算法.txt"));
 8     objectStructure.Add(new File("mm.png"));
 9     objectStructure.Show();
10 }

访问者模式的优缺点:

  优点:

    1)各角色职责分离,符合单一职责原则

    2)具有优秀的扩展性,使得数据结构和作用于结构上的操作解耦,使得操作集合可以独立变化。

    3)灵活性

  缺点:

    1)具体元素对访问者公布细节,违反了迪米特原则

    2)具体元素变更比较困难。

    3)违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

访问者模式的使用场景:

  1)对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。

  2)需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。  

参考:https://www.cnblogs.com/zyrblog/p/9244754.html

(0)

相关推荐

  • 设计模式(十六)——访问者模式

    设计模式(十六)——访问者模式

  • PHP设计模式—访问者模式

    定义: 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 结构: Visitor:抽象访问者,为该对象结构中Co ...

  • 诚之和:设计模式之什么是访问者模式

    本篇内容介绍了"设计模式之什么是访问者模式"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学 ...

  • 软件设计模式修炼 -- 访问者模式

    访问者模式是一种较为复杂的行为型设计模式,它包含访问者和被访问元素两个主要组成部分,这些被访问的元素具有不同的类型,且不同的访问者可以对其进行不同的访问操作 模式动机 对于系统中某些对象,它们存储在同 ...

  • 访问者模式

    假设有男人和女人两种元素,要分别打印出他们在不同状态时的不同表现. 用OO的思想把表现(行为)提取出来作为一个抽象方法,代码如下: 用if-else对状态进行判断  Person接口 public i ...

  • C#设计模式学习笔记:(21)访问者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8135083.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第九个模式--访 ...

  • 设计模式-行为型-状态模式

    状态模式(State): 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到,然后使用if else语句来做状态判断来进行不同情况的处理 ...

  • 设计模式-行为型-模板模式

    模板模式(Template): 提到模板,可能大多数人想到的是"简历模板"."论文模板"等,比如我们要写简历时,会从网上下载一份漂亮的简历模板,其格式是固定的, ...

  • 设计模式-创建型-建造者模式

    引言: 无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮.底盘.发动机.方向盘等各种部件.而对于大部分用户而言,无须知道这些部件的装配细节,也几乎不会 ...

  • 设计模式-创建型-工厂模式

    工厂设计模式: 顾名思义,该模式是用来生产对象的.在面向对象的设计模式中,万物皆对象,若使用new来创建对象,就会对该对象产生强耦合,假如我们需要更换该对象,那么使用该对象的对象都需要进行修改,这显然 ...

  • PHP设计模式之访问者模式

    PHP设计模式之访问者模式 访问者,就像我们去别人家访问,或者别人来我们家看望我们一样.我们每个人都像是一个实体,而来访的人都会一一的和我们打招呼.毕竟,我们中华民族是非常讲究礼数和好客的民族.访问者 ...

  • [PHP小课堂]PHP设计模式之访问者模式

    [PHP小课堂]PHP设计模式之访问者模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料