博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第23章 访问者模式(Visitor Pattern)
阅读量:6297 次
发布时间:2019-06-22

本文共 3227 字,大约阅读时间需要 10 分钟。

原文 

访问者模式

 

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

 

    概述:

 

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

 

    结构图:

 

    举例:

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://cflta.baihongyu.com/

你可能感兴趣的文章
【深度学习笔记】(二)Hello, Tensorflow!
查看>>
Spring Boot Admin 2.0开箱体验
查看>>
vue-router如何在router-link标签绑定click点击事件、keyup、change等事件
查看>>
20.17 shell中的函数
查看>>
css 三角形
查看>>
从输入 URL 到页面加载完成的过程中都发生了什么
查看>>
JVM汇总--类加载/收集器
查看>>
11.3/11.4/11.5 MySQL安装
查看>>
10.30 linux和windows互传文件,用户配置文件和密码配置文件,用户组管理,用户管理...
查看>>
《App架构师实践指南》:移动开发的进阶指南
查看>>
App研发录读后总结(一)
查看>>
ECS TAG功能详解
查看>>
gulp学习记录
查看>>
老男人面试第四家第五家-初创公司和b轮公司
查看>>
技术工坊|解密区块链DApp的代码逻辑,从请求到数据存储都要经历什么?(上海)...
查看>>
python访问memcached
查看>>
自动化运维系列之Cobbler (资源)
查看>>
VMware vSphere 服务器虚拟化部署安装图解(资源)
查看>>
开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
查看>>
外观设计模式(门面模式)
查看>>