访问者模式
•
表示
一个作用于某对象结构中的各个元素的操作。它使你可以在不改变各个元素的类的前提下定义作用于这些元素的新操作。
•
VisitorPattern
•
Representan operation to be performed on the elements of an
objectstructure
. Visitor letsyou define a new operation without changing the classes of the elements onwhich it operates.
基本概述
•
当一个集合中有若干个对象时,习惯上将这些对象称作集合中的元素,访问者模式可以使得我们在不改变集合中各个元素的类的前提下定义作用于这些元素上的新操作。
•
在编写类的时候,可能在该类中编写了若干个实例方法,该类的对象通过调用这些实例方法操作其成员变量表明所产生的行为。在某些设计中,可能需要定义作用于类的成员变量的新操作,而这个新操作不应当由该类中的某个实例方法来承担。比如电表是能显示用电的度数而不能计算电费的多少,这个是要抄表员抄取度数之后算出费用,这里电表我们称为被访问者而抄表员则是访问者。
•
模式的结构中包括五种
角色
•
抽象元素(
Element
):一个抽象类,该类定义了接收访问的
accept
操作。
•
具体元素(
ConcreteElement
)
:
Element
的子类。
•
对象结构(
ObjectStructure
):一个集合,用于存放
Element
对象,提供遍历它自己的方法。
•
抽象访问者(
Visitor
):一个接口,该接口定义操作对象(
ConcreteElement
)的方法。
•
具体访问者(
ConcreteVisitor
):实现
Visitor
接口的类。
•
以电表为例
•
电表抽象类
•
电表
•
一定范围内的电表,如:一栋大楼
•
抄表员
•
具体的一个抄表员
模式的UML类图
模式结构的描述与使用实例
•
1
.抽象元素(
Element
)
:
Student.java
•
public abstract class Student{
•
public abstract void accept(Visitor v);
•
}
•
2
.具体
元素
(
Concrete Element
)
_1:
Undergraduate.java
•
public class Undergraduate extends Student{
•
double math,english; //
成绩
•
String name;
•
Undergraduate(String name,doublemath,double english){
•
this.name=name;
•
this.math=math;
•
this.english=english;
•
}
•
public doublegetMath(){
•
return math;
•
}
•
public double getEnglish(){
•
return english;
•
}
•
public String getName(){
•
return name;
•
}
•
public void accept(Visitor v){
•
v.visit(this);
•
}
•
}
•
2
.
具体元素(
Concrete Element
)
_2:
GraduateStudent.java
•
public classGraduateStudent extends Student{
•
doublemath,english,physics; //
成绩
•
String name;
•
GraduateStudent(String name,double math,double
english,double
physics){
•
this.name=name;
•
this.math=math;
•
this.english=english;
•
this.physics=physics;
•
}
•
publicdouble getMath(){
•
return math;
•
}
•
publicdouble getEnglish(){
•
return english;
•
}
•
public doublegetPhysics(){
•
return physics;
•
}
•
publicString getName(){
•
return name;
•
}
•
publicvoid accept(Visitor v){
•
v.visit(this);
•
}
•
}
•
3
.对象结构(
Object Structure
)
•
本问题中,我们让该角色是
java.util
包中的
ArrayList
集合
•
4
.抽象访问者(
Visitor
)
:
Visitor.java
•
•
publicinterface Visitor{
•
public void visit(Undergraduate stu);
•
public void visit(GraduateStudent stu);
•
}
•
5
.具体访问者(
ConcreteVisitor
)
:
Company.java
•
public class Company implements Visitor{
•
public voidvisit(Undergraduate stu){
•
doublemath=
stu.getMath
();
•
doubleenglish=
stu.getEnglish
();
•
if(math>80&&english>90)
•
System.out.println(
stu.getName
()+"
被录用
");
•
}
•
public voidvisit(GraduateStudent stu){
•
doublemath=
stu.getMath
();
•
doubleenglish=
stu.getEnglish
();
•
doublephysics=
stu.getPhysics
();
•
if(math>80&&english>90&&physics>70)
•
System.out.println(
stu.getName
()+"
被录用
");
•
}
•
}
•
6
.应用
:
Application.java
•
import
java.util
.*;
•
public class Application{
•
publicstatic void main(String
args
[]) {
•
Visitor visitor=new Company();
•
ArrayList<Student>
studentList
=new ArrayList<Student>();
•
Student student=null;
•
studentList.add
(student=newUndergraduate("
张三
",67,88));
•
studentList.add
(student=newUndergraduate("
李四
",90,98));
•
studentList.add
(student=newUndergraduate("
将粼粼
",85,92));
•
studentList.add
(student=newGraduateStudent("
刘名
",88,70,87));
•
studentList.add
(student=newGraduateStudent("
郝人
",90,95,82));
•
Iterator<Student>
iter
=
studentList.iterator
();
•
while(
iter.hasNext
()){
•
Student stu=
iter.next
();
•
stu.accept
(visitor);
•
}
•
}
•
}
访问者模式的优点
•
可以在不改变一个集合中的元素的类的情况下,增加新的施加于该元素上的新操作。
•
可以将集合中各个元素的某些操作集中到访问者中,不仅便于集合的维护,也有利于集合中元素的复用。