『设计模式』我能进来坐坐吗?-访问者模式

『设计模式』我能进来坐坐吗?-访问者模式

23 种设计模式+额外常用设计模式汇总 (持续更新)

访问者模式

访问者( Visitor )模式的定义: 将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作, 为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。

优点:

① 扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。
② 复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。
③ 灵活性好。访问者模式将数据结构与作用于结构上的操作解嘱, 使得操作集合可相对自由地
演化而不影响系统的数据结构。
④ 符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问
者的功能都比较单一。

缺点:

① 增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作, 这违背了“开闭原则” 。
② 破坏封装。访问者模式中具体元素对访问者公布细节, 这破坏了对象的封装性。
③ 违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。

使用场景: 1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作”污染”这些对象的类,也不希望在增加新操作时修改这些类。

应用场景

对象结构相对稳定,但其操作算法经常变化的程序。
对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。
对象结构包含很多类型的对象,希望对这些对象实施一些依赖于其具体类型的操作。

实现

模式的结构
访问者模式包含以下主要角色。
( 1 )抽象访问者( Visitor )角色: 定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作visitXXX() ,该操作中的参数类型标识了被访问的具体元素。
( 2 ) 具体访问者( Concrete Visitor )角色: 实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。
( 3 )抽象元素( Element )角色: 声明一个包含接受操作accept()的接口,被接受的访问者对象作为accept()方法的参数。
( 4 )具体元素( Concrete Element )角色:实现抽象元素角色提供的accept()操作,其方法体通常都是 visitor.visit(this) ,另外具体元素中可能还包含本身业务逻辑的相关操作。
( 5 )对象结构(Object Structure ) 角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现。
UML:
在这里插入图片描述

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
//VisitorTest.java
package Visitor;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

interface Visitor {
void visit(ConcreteElementA element);

void visit(ConcreteElementB element);
}




//抽象访问者


//具体访问者A类
class ConcreteVisitorA implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者A访问-->" + element.operationA());
}

public void visit(ConcreteElementB element) {
System.out.println("具体访问者A访问-->" + element.operationB());
}
}

//具体访问者B类
class ConcreteVisitorB implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者B访问-->" + element.operationA());
}

public void visit(ConcreteElementB element) {
System.out.println("具体访问者B访问-->" + element.operationB());
}
}


//抽象元素类
interface Element {
void accept(Visitor visitor);
}

//具体元素A类
class ConcreteElementA implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}

public String operationA() {
return "具体元素A的操作。";
}
}

//具体元素B类
class ConcreteElementB implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}

public String operationB() {
return "具体元素B的操作。";
}
}
//对象结构角色
class ObjectStructure {
private List<Element> list = new ArrayList<Element>();

public void accept(Visitor visitor) {
Iterator<Element> i = list.iterator();
while (i.hasNext()) {
((Element) i.next()).accept(visitor);
}
}

public void add(Element element) {
list.add(element);
}

public void remove(Element element) {
list.remove(element);
}
}


public class VisitorTest {

public static void main(String[] args) {
ObjectStructure os = new ObjectStructure();
os.add(new ConcreteElementA());
os.add(new ConcreteElementB());
Visitor visitor = new ConcreteVisitorA();
os.accept(visitor);
System.out.println("------------------------");
visitor = new ConcreteVisitorB();
os.accept(visitor);
}
}

我们再举一个客户管理系统的例子
用户位个人用户,企业用户
提出服务申请、客户价值分析、客户对产品偏好
在这里插入图片描述

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
package CRM;



public interface Customer {

public void accpet(Visitor vis);

}



package CRM;



public class Enterprise implements Customer {

@Override

public void accpet(Visitor vis) {

// TODO Auto-generated method stub

vis.visit(this);

}

public String oper()

{

return "企业用户";

}

}



package CRM;



public class Personal implements Customer {

@Override

public void accpet(Visitor vis) {

// TODO Auto-generated method stub

vis.visit(this);

}

public String oper()

{

return "个人用户";

}

}



package CRM;



public interface Visitor {

public void visit(Enterprise ent);

public void visit(Personal per);

}



package CRM;







public class Service_ApplyFor implements Visitor{





@Override

public void visit(Enterprise ent) {

// TODO Auto-generated method stub

System.out.println(ent.oper()+"提出企业用户的服务申请");

}



@Override

public void visit(Personal per) {

// TODO Auto-generated method stub

System.out.println(per.oper()+"提出个人用户的服务申请");

}



}



package CRM;







public class Customer_AnalyzePrefer implements Visitor{





@Override

public void visit(Enterprise ent) {

// TODO Auto-generated method stub

System.out.println("对"+ent.oper()+"提供企业用户的客户产品偏好分析");

}



@Override

public void visit(Personal per) {

// TODO Auto-generated method stub

System.out.println("对"+per.oper()+"提供个人用户的客户产品偏好分析");

}



}



package CRM;







public class Customer_AnalyzeValue implements Visitor{





@Override

public void visit(Enterprise ent) {

// TODO Auto-generated method stub

System.out.println("对"+ent.oper()+"提供企业用户的客户价值分析");

}



@Override

public void visit(Personal per) {

// TODO Auto-generated method stub

System.out.println("对"+per.oper()+"提供个人用户的客户价值分析");

}



}



package CRM;



import java.util.ArrayList;

import java.util.List;







public class Manage_System {

private List<Customer> OperList = new ArrayList<>();



public void accept(Visitor vis) {

for (Customer cus : OperList) {

cus.accpet(vis);

}

}



public void add(Customer cus)

{

OperList.add(cus);

}

public void remove(Customer cus)

{

OperList.remove(cus);

}

}



package CRM;



public class Client {



public static void main(String[] args) {

// TODO Auto-generated method stub

Manage_System MS = new Manage_System();

MS.add(new Personal());

MS.add(new Enterprise());

Visitor vis=new Customer_AnalyzePrefer();

MS.accept(vis);

vis=new Customer_AnalyzeValue();

MS.accept(vis);

vis=new Service_ApplyFor();

MS.accept(vis);

}



}

『设计模式』我能进来坐坐吗?-访问者模式
https://chiamzhang.github.io/2024/06/29/『设计模式』我能进来坐坐吗?-访问者模式/
Author
Chiam
Posted on
June 29, 2024
Licensed under