第23章 访问者模式(Visitor Pattern)

时间:2022-09-26 10:26:42

原文 第23章 访问者模式(Visitor Pattern)

访问者模式

导读:访问者模式是我个人认为所有行为模式中最为复杂的一种模式了,这个模式可能看一遍会看不懂,我也翻了好几个例子,依然不能很好的理解访问者模式的核心。下面这个例子是来源于大话设计模式中的例子,稍作了修改!后续如果我有更好的例子或者想法我会对本章进行完善。

概述:

 

一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作(神一般的语言)。

结构图:

第23章 访问者模式(Visitor Pattern)

 

    举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
   /// <summary>
    /// 抽象元素类:接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。抽象元素一般有两类方法,一部分是本身的业务逻辑,另外就是允许接收哪类访问者来访问。
    /// </summary>
    public abstract class Person
    {
        public abstract void Accept(Visitor visitor);
    }
    /// <summary>
    /// 元素类:实现抽象元素类所声明的accept方法,通常都是visitor.visit(this),基本上已经形成一种定式了。
    /// </summary>
    public class Woman : Person
    {
 
        public override void Accept(Visitor visitor)
        {
            visitor.visit(this);
        }
    }
 
    /// <summary>
    /// 元素类:实现抽象元素类所声明的accept方法,通常都是visitor.visit(this),基本上已经形成一种定式了。
    /// </summary>
    public class Man : Person
    {
 
        public override void Accept(Visitor visitor)
        {
            visitor.visit(this);
        }
    }
 
 
 
    /// <summary>
    /// 抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法中的参数定义哪些对象是可以被访问的
    /// </summary>
    public interface Visitor
    {
         void visit(Man man);
         void visit(Woman girl);
    }
 
    /// <summary>
    /// 访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情。
    ///  成功时Man与Woman的不同表现   
    /// </summary>
    public class Success : Visitor
    {
 
        public void visit(Man man)
        {
            Console.WriteLine("当男人成功时,背后多半有一个伟大的女人");
        }
 
 
        public void visit(Woman woman)
        {
            Console.WriteLine("当女人成功时,背后大多有一个不成功的男人");
        }
    }
 
 
    /// <summary>
    /// 访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情。
    ///  恋爱时Man与Woman的不同表现 
    /// </summary>
    public class Love : Visitor
    {
 
        public void visit(Man man)
        {
            Console.WriteLine("当男人恋爱时,凡事不懂也装懂");
        }
 
 
        public void visit(Woman girl)
        {
            Console.WriteLine("当女人恋爱时,遇事懂也装不懂");
        }
    }
    /// <summary>
    /// 结构对象:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如List、Set、Map等,在项目中一般很少抽象出这个角色
    /// </summary>
    public class ObjectStructure
    {
        private List<Person> elements = new List<Person>();
 
        public void attach(Person element)
        {
            elements.Add(element);
        }
 
        public void detach(Person element)
        {
            elements.Remove(element);
        }
 
        //遍历各种具体元素并执行他们的accept方法   
        public void display(Visitor visitor)
        {
            foreach (var item in elements)
            {
                item.Accept(visitor);
            }
 
        }
    }

客户端调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 class Program
    {
        static void Main(string[] args)
        {
            ObjectStructure o = new ObjectStructure();  //依赖于ObjectStructure   
            //实例化具体元素   
            o.attach(new Man());
            o.attach(new Woman());
 
            //当成功时不同元素的不同反映   
            Visitor success = new Success();           //依赖于抽象的Visitor接口   
            o.display(success);
 
            //当恋爱时的不同反映   
            Visitor amativeness = new Love();          //依赖于抽象的Visitor接口   
            o.display(amativeness);
            Console.ReadLine();
        }
    }

适用场景:

 

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

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

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

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

特点及优缺点:

1、访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对*地演化。

2、访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。

3、访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。

设计模式系列文章入口:http://www.diyibk.com/post/39.html

第23章 访问者模式(Visitor Pattern)的更多相关文章

  1. 乐在其中设计模式&lpar;C&num;&rpar; - 访问者模式&lpar;Visitor Pattern&rpar;

    原文:乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) 作者:webabc ...

  2. 二十四种设计模式:访问者模式&lpar;Visitor Pattern&rpar;

    访问者模式(Visitor Pattern) 介绍表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 示例有一个Message实体类,某些对象对 ...

  3. 访问者模式&lpar;Visitor Pattern&rpar;——操作复杂对象结构

    模式概述 在软件开发中,可能会遇到操作复杂对象结构的场景,在该对象结构中存储了多个不同类型的对象信息,而且对同一对象结构中的元素的操作方式并不唯一,可能需要提供多种不同的处理方式,还有可能增加新的处理 ...

  4. &lbrack;设计模式&rsqb; 23 访问者模式 visitor Pattern

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

  5. C&num;设计模式——访问者模式&lpar;Visitor Pattern&rpar;

    一.概述由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改.对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能.二.访问 ...

  6. 十一个行为模式之访问者模式&lpar;Visitor Pattern&rpar;

    定义: 提供一个作用于某对象结构(通常是一个对象集合)的操作的接口,使得在添加新的操作或者在添加新的元素时,不需要修改原有系统,就可以对各个对象进行操作. 结构图: Visitor:抽象访问者类,对元 ...

  7. 访问者模式-Visitor Pattern

    1.主要优点 访问者模式的主要优点如下: (1) 增加新的访问操作很方便.使用访问者模式,增加新的访问操作就意味着增加一个新的具体访问者类,实现简单,无须修改源代码,符合“开闭原则”. (2) 将有关 ...

  8. 设计模式之第20章-访问者模式&lpar;Java实现&rpar;

    设计模式之第20章-访问者模式(Java实现) “嘿,你脸好红啊.”“精神焕发.”“怎么又黄了?”“怕冷,涂的,涂的,蜡.”“身上还有酒味,露馅了吧,原来是喝酒喝的啊.”“嘿嘿,让,让你发现了,今天来 ...

  9. 设计模式 &lpar; 二十 &rpar; 访问者模式Visitor(对象行为型)

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

随机推荐

  1. Android SDK Tools Platform-tools Build-tools

    (1)Android SDK (Android SDK主安装包,包含SDK Manager.AVD Manager.工具包tools,释放后的根文件夹为android-sdk-windows): re ...

  2. Hibernate 性能优化之查询缓存

    查询缓存是建立在二级缓存基础之上的,所以与二级缓存特性相似,是共享的,适合修改不是很频繁的数据 查询缓存不是默认开启的,需要设置      1.在cfg文件中配置 <property name= ...

  3. &lbrack;转&rsqb;为什么移动Web 应用程序很慢

    原文出处: Herb Sutter   译文出处: tangzhnju 我写过不少文章来讨论为什么移动Web应用程序很慢,这也引起了不少的讨论.但是不幸的是,这些讨论没有像我喜欢的那样的基于事实. 所 ...

  4. bzoj 3620&colon; 似乎在梦中见过的样子

    Description "Madoka,不要相信 QB!"伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约. 这是 Modoka 的一个噩梦,也同时是上个轮回 ...

  5. 基于JDK1&period;8的ConcurrentHashMap分析

    之前看过ConcurrentHashMap的分析,感觉也了解的七七八八了.但昨晚接到了面试,让我把所知道的ConcurrentHashMap全部说出来. 然后我结结巴巴,然后应该毫无意外的话就G了,今 ...

  6. selenium启动谷歌浏览器

    谷歌浏览器可以是任意版本. 根据谷歌浏览器的版本,下载响应的浏览器驱动(百度:谷歌驱动与谷歌浏览器版本映射表). 我用的是win7 ,下载win32就行了.下载解压之后可以放在python的安装目录下 ...

  7. 如何使用VSTO自动将Excel中的图表复制到Word

    如何使用VSTO自动将Excel中的图表复制到Word 原文地址:https://code.msdn.microsoft.com/How-to-copy-Chart-in-Excel-a29f9029 ...

  8. ASP&period;NET MVC 3升级至MVC 5&period;1的遭遇:&OpenCurlyDoubleQuote;已添加了具有相同键的项”

    最近将一个项目从ASP.NET MVC 3升级至刚刚发布的ASP.NET MVC 5.1,升级后发现一个ajax请求出现了500错误,日志中记录的详细异常信息如下: System.ArgumentEx ...

  9. Linux-I&sol;O五种模型

    一. 概念说明 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 I/O 同步(Sync)/异步(Async) 阻塞(Block)/非阻塞(Unbloc ...

  10. 【最大流】POJ3236-ACM Computer Factory

    [题意] 装配一个电脑需要P个零件,现在给出N机器的信息,每个机器可以将k个电脑由状态{S1,S2..,Sp}转变为{Q1,Q2..,Qp},问最多能装配多少台电脑以及对应的方案? [思路] 1A.. ...