原文 第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. AndroidAnnotations说明—AndroidAnnotations它是如何工作的?

    AndroidAnnotations它的工作原理很easy,它使用标准java注塑加工工具,自己主动加她一个额外的步骤生成源代码编译.         源代码是什么?每个增强的类.比方每个用@EAct ...

  2. 自定义DB连接池实现

    实现一个简单的数据库连接池 1,连接池接口 package dbsource; import java.sql.Connection; import java.sql.SQLException; /* ...

  3. ServiceStack.Hello——跨平台.net REST api服务搭建

    ServiceStack.Hello--跨平台.net REST api服务搭建 自己创建: https://github.com/ServiceStack/ServiceStack/wiki/Cre ...

  4. 在C#主线程和子线程将数据传递给对方如何实现

    在C#中主线程和子线程怎样实现互相传递数据 老帅 在C#中创建线程Thread时,能够有多种方法,而主线程和子线程之间又怎样实现互相传递数据,每种创建方法传递參数的效果是不同的,逐一看一下:  一.不 ...

  5. [LeetCode62]Unique Paths

    题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...

  6. JS弄ASP.NET(C#)在页GridView信息选择行

    做web发展还是新手我,为了之前获得Gridview中间值,它是通过服务器端控件通过第一Gridview将数据保存到服务器,当一个服务器,然后绑定的隐藏字段,在通过的js阅读隐藏字段值,如今,这种方法 ...

  7. Android - 用Fragments实现动态UI - 使用Android Support Library

    Android Support Library提供了一个带有API库的JAR文件来让你可以在使用最新的Android API的同时也也已在早期版本的Android上运行.例如,Support Libr ...

  8. 2014 I/O返回:Google连接一切

    文/蒋涛 6月.WWDC 2014与Google I/O  (大部分演讲视频都公开.Youtube须要FQ.很值得一看)相继召开. 今年是我第三年參加Google I/O大会.三年间,Google积累 ...

  9. C#枚举数和迭代器

    大道至简,始终认为简洁是一门优秀的编程语言的一个必要条件.相对来说,C#是比较简洁的,也越来越简洁.在C#中,一个关键字或者语法糖在编译器层面为我们做了很多乏味的工作,可能实现的是一个设计模式,甚至是 ...

  10. JDBC在getConnection之前为什么要调用Class.forName(转)

    获取一个数据库连接的通用模板如下: String driver = "oracle.jdbc.OracleDriver"; String url = "jdbc:orac ...