设计模式之访问者模式

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 17:16   2277   0

访问者模式

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

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);
}
}
}

访问者模式的优点

可以在不改变一个集合中的元素的类的情况下,增加新的施加于该元素上的新操作。
可以将集合中各个元素的某些操作集中到访问者中,不仅便于集合的维护,也有利于集合中元素的复用。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP