23个java设计模式(二十一)-- 访问者模式

2016年03月28日 原创
关键词: java 设计模式
摘要 访问者模式是一个作用于某对象结构中的各个元素的操作。它可以在不改变各个元素的类的前提下定义作用于这些元素的新操作。

一、概述。

访问者模式是一个作用于某对象结构中的各个元素的操作。它可以在不改变各个元素的类的前提下定义作用于这些元素的新操作。

编写类的时候,可能在该类中编写了若干个实例方法,该类的对象通过调用这些实例方法操作其成员变量表明所产生的行为。在某些设计中,可能需要定义作用于类的成员变量的新操作,而且这个新操作不应当由该类中的某个实例方法来承担。这是就需要使用访问者模式。

二、访问者模式的结构。

访问者模式包括5种角色:

  • 抽象元素(Element):一个抽象类,定义了接受访问者的accept操作。
  • 具体元素(Concrete Element):Element的子类。
  • 对象结构(Object Structure):一个集合,用于存放Element对象,提供遍历它自己的方法。
  • 抽象访问者(Visitor):一个接口,该接口定义操作具体对象的方法。
  • 具体访问者(Concrete Visitor):实现Visitor接口的类。

三、示例程序。

抽象元素(Element)

Student.java

public abstract class Student {
	public abstract void accept(Visitor v);
}

具体元素(Concrete Element)

Undergraduate.java

public class Undergraduate extends Student{
	private double math, english;
	private String name;
	public Undergraduate(double math, double english, String name) {
		this.math = math;
		this.english = english;
		this.name = name;
	}
	public double getMath() {
		return math;
	}
	public double getEnglish() {
		return english;
	}
	public String getName() {
		return name;
	}
	@Override
	public void accept(Visitor v) {
		v.visit(this);
	}
	
}

GraduateStudent.java

public class GraduateStudent extends Student{
	private double math,english,physics;
	private String name;
	public GraduateStudent(double math, double english, double physics,
			String name) {
		this.math = math;
		this.english = english;
		this.physics = physics;
		this.name = name;
	}
	public double getMath() {
		return math;
	}
	public double getEnglish() {
		return english;
	}
	public double getPhysics() {
		return physics;
	}
	public String getName() {
		return name;
	}
	@Override
	public void accept(Visitor v) {
		v.visit(this);
	}
	
}

对象结构(Object Structure)

本示例中,该角色是java.util包中的ArrayList集合。

抽象访问者(Visitor)

Visitor.java

public interface Visitor {
	void visit(Undergraduate stu);
	void visit(GraduateStudent stu);
}
具体访问者(Concrete Visitor)

Company.java

public class Company implements Visitor{

	@Override
	public void visit(Undergraduate stu) {
		if(stu.getMath()>80&&stu.getEnglish()>90)System.out.println(stu.getName()+"被录用");
	}

	@Override
	public void visit(GraduateStudent stu) {
		if(stu.getMath()>80&&stu.getEnglish()>90&&stu.getPhysics()>70)System.out.println(stu.getName()+"被录用");
	}

}

测试程序

Example1Test.java

public class Example1Test {
	@Test
	public void testMain() {
		Visitor visitor = new Company();
		ArrayList<Student> studentList = new ArrayList<Student>();
		studentList.add(new Undergraduate(67, 88, "张三"));
		studentList.add(new Undergraduate(90, 98, "李四"));
		studentList.add(new Undergraduate(85,92,"王五"));
		studentList.add(new GraduateStudent(88, 70, 87, "小明"));
		studentList.add(new GraduateStudent(90, 95, 82, "小王"));
		Iterator<Student> iterator = studentList.iterator();
		while(iterator.hasNext()) {
			iterator.next().accept(visitor);
		}
	}
}

四、访问者模式的优点。

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

五、适合访问者模式的情景。

  1. 一个对象结构中,比如某个集合中,包含很多对象,想对集合中的对象增加一些新的操作。
  2. 需要对集合中的对象进行很多不同的并且不相关的操作,而又不想修改对象的类。