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

简介: 原文 第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

目录
相关文章
|
机器学习/深度学习 人工智能 网络架构
Transformer原理解析——一种Open AI和DeepMind都在用的神经网络架构
Transformer模型是一种日益流行的神经网络结构。它最近被OpenAI用于他们的语言模型中。与此同时,近期也被DeepMind用于它们的程序“星际争霸”中击败了一名顶级职业星际玩家。 Transformer模型的开发是为了解决序列转换及神经机器翻译问题。
9071 0
|
机器学习/深度学习 传感器 人工智能
AI与未来医疗:重塑健康管理新格局随着人工智能(AI)技术的飞速发展,医疗行业正迎来一场前所未有的变革。AI不仅在数据分析、诊断支持方面展现出巨大潜力,还在个性化治疗、远程医疗等多个领域实现了突破性进展。本文将探讨AI技术在医疗领域的具体应用及其对未来健康管理的影响。
人工智能(AI)正在彻底改变医疗行业的面貌。通过深度学习算法和大数据分析,AI能够迅速分析海量的医疗数据,提供精准的诊断和治疗建议。此外,AI在远程医疗、药物研发以及患者管理等方面也展现出了巨大的潜力。本文将详细探讨这些技术的应用实例,并展望其对健康管理的深远影响。
|
10月前
|
人工智能 自然语言处理 搜索推荐
AI 赋能:开启内容生产效率革命的密钥》
在数字化时代,AI技术正成为提高内容生产效率的关键工具。本文探讨了AI在文章写作、文案创作、翻译、图像识别与生成及数据分析等方面的应用,分析了其提高效率的方式、带来的优势与挑战,并通过新闻媒体、营销、教育等行业案例,展望了AI在内容生产领域的未来。
459 3
|
11月前
|
人工智能 搜索推荐 数据可视化
销售易:国产CRM测评中的佼佼者
销售易是一款功能强大、服务优质的国产CRM系统,涵盖线索管理、销售流程、客户管理、合同与回款、数据分析等全方位服务。其界面简洁、交互友好,支持移动应用,确保业务连续性。销售易以客户为中心,持续创新,坚持诚信正直,为企业提供高性价比的CRM解决方案。
|
机器学习/深度学习 人工智能 安全
AI在灾害管理中的作用:提高防灾减灾能力
【10月更文挑战第8天】AI技术在灾害管理中的应用正在逐步改变我们对灾害的应对方式。通过发挥AI的优势,我们可以更有效地预防、减轻和应对自然灾害带来的挑战,为构建安全、弹性的社会做出更大贡献。
|
消息中间件 Java 微服务
Eureka介绍与使用
Eureka介绍与使用
|
Java 关系型数据库 MySQL
浪漫编码:手把手教你实现校园表白墙功能
浪漫编码:手把手教你实现校园表白墙功能
242 0
|
人工智能 IDE 开发工具
给IntelliJ IDEA添加AI功能
这篇文章讲解了如何在IntelliJ IDEA中安装和使用阿里云开发的通义灵码插件,以增强IDE的人工智能辅助编程功能。
3895 0
给IntelliJ IDEA添加AI功能
|
对象存储 数据库
2025年 | 10月云大使推广奖励规则
云大使推广返利活动,企业新用户下单返佣加码5%,推广最高返佣45%,新老用户都可参与返利活动。
99395 52
|
机器学习/深度学习 自然语言处理 安全
计算机在国家安全中的作用
计算机在国家安全中的作用
294 0