訪問者模式是一種行為設計模式,?它能將算法與其所作用的對象隔離開來。
訪問者模式建議將新行為放入一個名為訪問者的獨立類中,?而不是試圖將其整合到已有類中。?現在,?需要執行操作的原始對象將作為參數被傳遞給訪問者中的方法,?讓方法能訪問對象所包含的一切必要數據。
訪問者模式結構
訪問者?(Visitor)?接口聲明了一系列以對象結構的具體元素為參數的訪問者方法。?如果編程語言支持重載,?這些方法的名稱可以是相同的,?但是其參數一定是不同的。
具體訪問者?(Concrete Visitor)?會為不同的具體元素類實現相同行為的幾個不同版本。
元素?(Element)?接口聲明了一個方法來?“接收”?訪問者。?該方法必須有一個參數被聲明為訪問者接口類型。
具體元素?(Concrete Element)?必須實現接收方法。?該方法的目的是根據當前元素類將其調用重定向到相應訪問者的方法。?請注意,?即使元素基類實現了該方法,?所有子類都必須對其進行重寫并調用訪問者對象中的合適方法。
客戶端?(Client)?通常會作為集合或其他復雜對象?(例如一個組合樹)?的代表。?客戶端通常不知曉所有的具體元素類,?因為它們會通過抽象接口與集合中的對象進行交互。
JAVA 示例代碼:
import java.util.*;
public class VisitorPattern {
? ? public static void main(String[] args) {
? ? ? ? PersonStructure structure = new PersonStructure();
? ? ? ? Visitor1 visitor1 = new Visitor1();
? ? ? ? System.out.println("訪問者1的訪問記錄:");
? ? ? ? structure.Accept(visitor1);
? ? ? ? System.out.println("學生年齡的總和:" + visitor1.getStudentAgeSum() + " 老師年齡的總和:" + visitor1.getTeacherAgeSum());
? ? ? ? System.out.println("=========================================");
? ? ? ? Visitor2 visitor2 = new Visitor2();
? ? ? ? System.out.println("訪問者2的訪問記錄:");
? ? ? ? structure.Accept(visitor2);
? ? ? ? System.out.println("學生的最高成績:" + visitor2.getMaxScore() + " 老師的最高工齡:" + visitor2.getMaxWorkYear());
? ? }
}
interface Visitor {
? ? public void visitStudent(Student student); // 訪問學生
? ? public void visitTeacher(Teacher teacher); // 訪問老師
}
class Visitor1 implements Visitor { // 訪問者1 分別統計學生和老師的年齡總和
? ? private int studentAgeSum = 0;
? ? private int teacherAgeSum = 0;
? ? public int getStudentAgeSum() {
? ? ? ? return studentAgeSum;
? ? }
? ? public int getTeacherAgeSum() {
? ? ? ? return teacherAgeSum;
? ? }
? ? @Override
? ? public void visitStudent(Student student) {
? ? ? ? System.out.println("訪問者1訪問學生:" + student.getName() + " 年齡:" + student.getAge());
? ? ? ? studentAgeSum += student.getAge();
? ? }
? ? @Override
? ? public void visitTeacher(Teacher teacher) {
? ? ? ? System.out.println("訪問者1訪問老師:" + teacher.getName() + " 年齡:" + teacher.getAge());
? ? ? ? teacherAgeSum += teacher.getAge();
? ? }
}
class Visitor2 implements Visitor { // 訪問者2 分別求出 學生的最高成績 以及 老師的最高工齡
? ? private int maxScore = -1;
? ? private int maxWorkYear = -1;
? ? public int getMaxScore() {
? ? ? ? return maxScore;
? ? }
? ? public int getMaxWorkYear() {
? ? ? ? return maxWorkYear;
? ? }
? ? @Override
? ? public void visitStudent(Student student) {
? ? ? ? System.out.println("訪問者2訪問學生:" + student.getName() + " 成績:" + student.getScore());
? ? ? ? maxScore = Math.max(maxScore, student.getScore());
? ? }
? ? @Override
? ? public void visitTeacher(Teacher teacher) {
? ? ? ? System.out.println("訪問者2訪問老師:" + teacher.getName() + " 工齡:" + teacher.getWorkYear());
? ? ? ? maxWorkYear = Math.max(maxWorkYear, teacher.getWorkYear());
? ? }
}
class PersonStructure {
? ? private List<Person> personList = new ArrayList<Person>();
? ? public PersonStructure() {
? ? ? ? personList.add(new Student("張三", 20, 70));
? ? ? ? personList.add(new Student("李四", 21, 80));
? ? ? ? personList.add(new Student("王五", 22, 90));
? ? ? ? personList.add(new Teacher("李老師", 26, 3));
? ? ? ? personList.add(new Teacher("陳老師", 27, 4));
? ? ? ? personList.add(new Teacher("劉老師", 28, 5));
? ? }
? ? public void Accept(Visitor visitor) {
? ? ? ? // for (遍歷對象類型 對象名 : 遍歷對象)
? ? ? ? for (Person person : personList) {
? ? ? ? ? ? person.Accept(visitor);
? ? ? ? }
? ? }
}
abstract class Person {
? ? private String name;
? ? private int age;
? ? public Person(String name, int age) {
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? }
? ? public String getName() {
? ? ? ? return name;
? ? }
? ? public int getAge() {
? ? ? ? return age;
? ? }
? ? public abstract void Accept(Visitor visitor);
}
class Student extends Person {
? ? private int score;
? ? public Student(String name, int age, int score) {
? ? ? ? super(name, age);
? ? ? ? this.score = score;
? ? }
? ? public int getScore() {
? ? ? ? return score;
? ? }
? ? @Override
? ? public void Accept(Visitor visitor) {
? ? ? ? visitor.visitStudent(this);
? ? }
}
class Teacher extends Person {
? ? private int workYear;
? ? public Teacher(String name, int age, int workYear) {
? ? ? ? super(name, age);
? ? ? ? this.workYear = workYear;
? ? }
? ? public int getWorkYear() {
? ? ? ? return workYear;
? ? }
? ? @Override
? ? public void Accept(Visitor visitor) {
? ? ? ? visitor.visitTeacher(this);
? ? }
}