原文 第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. 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)

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

  2. 二十四种设计模式:访问者模式(Visitor Pattern)

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

  3. 访问者模式(Visitor Pattern)——操作复杂对象结构

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

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

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

  5. C#设计模式——访问者模式(Visitor Pattern)

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

  6. 十一个行为模式之访问者模式(Visitor Pattern)

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

  7. 访问者模式-Visitor Pattern

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

  8. 设计模式之第20章-访问者模式(Java实现)

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

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

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

随机推荐

  1. Quartz CronTrigger运用

    CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年]  序号 说明  是否必填  同意填写的值 同意的通配符  1  秒  是  0-59    , - ...

  2. CF 452A(Eevee-直接试)

    A. Eevee time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...

  3. myeclipse如何恢复已删除的文件和代码

    这是一篇文章分享秘诀:myeclipse恢复意外删除的文件和代码 [ 恢复误删文件 ] 今天在写代码的时候,不小心把一个包给删除了,然后这个包下全部的文件都没了,相信非常多人都有类似的经历. 幸好my ...

  4. redmine 出口中国的乱码

    pdf 这是redmine的bug.必须在个人账户更改将设立中国语文,足够的人才来解决. 顺便说一下,提示.以下更改文件的方法是无效的 /home/redmine/redmine-2.5.1/lib/ ...

  5. IIS使用 URL Rewrite Module 2.0组件 设置伪静态的方法

    简体中文版WIn10无法安装,需要改注册表, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp  MajorVersion 项,这个也是 dword 值 10 ...

  6. JVM的参数详解(转)

    12年毕业到先在处理第一年外这几年纯属于打酱油,当初自学Java然后就出来找工作了,还有第一家面试就通过了挺幸运的 但之后的这段时间一直是处于吃老本的状态.最近心情真的很不好,各种黄老邪!一直处于堕落 ...

  7. android中怎么把自己须要的app启动图标集中到一个弹出框中

    先看效果图 这个是我们自己的apk点击之后的效果 下边是布局文件 activity_main.xml主布局文件 <LinearLayout xmlns:android="http:// ...

  8. Html 5 坦克大战(韩顺平县版本号)

    html 5例如,下面的代码段: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/ ...

  9. 【Hibernate学习】 ——ORM(三)

    前面几种关系我们曾经就常常常使用,对于继承我们也并不陌生,常常接触的类与类之间的继承用extendskeyword,那么在表与表的关系中怎样表示呢?以下我们来讲继承映射. 继承有三种实现的策略,单表继 ...

  10. Visual Studio 2015使用EF6的DBFirst模式操作Sqlite数据库

    什么是DBFirst 1:到官方下载并安装32位驱动(如果你是旧版的驱动,卸载掉,然后下载最新版的,否则操作数据时会出现异常) 2:通过Nuget获取System.Data.SQLite(会默认把下面 ...