設計模式之訪問者模式

訪問者模式是一種行為設計模式,?它能將算法與其所作用的對象隔離開來。

訪問者模式建議將新行為放入一個名為訪問者的獨立類中,?而不是試圖將其整合到已有類中。?現在,?需要執行操作的原始對象將作為參數被傳遞給訪問者中的方法,?讓方法能訪問對象所包含的一切必要數據。


訪問者模式結構

訪問者?(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);

? ? }

}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 Google Play應用市場對于應用的targetSdkVersion有了更為嚴格的要求。從 2018 年...
    申國駿閱讀 64,581評論 14 98
  • 《來,我們說說孤獨》 1·他們都在寫孤獨 一個詩人 如果 不說說 內心的孤獨 不將孤獨 寫進詩里 是不是很掉價呢 ...
    聽太陽升起閱讀 4,389評論 1 7
  • 自幼貧民窟長大的女子,僥幸多念了兩本書,枉以為可以與人平起平坐。可是人生從來都是接力賽,我們卻天真的當成了百米沖刺...
    Leeanran閱讀 5,785評論 1 5
  • 云舒老師,姓甚名誰,男的女的,多大歲數,這些我全然不知。之所以要寫寫云舒老師,完全是因為他寫的文章,如一個巨大的磁...
    數豆者m閱讀 2,379評論 6 9
  • """1.個性化消息: 將用戶的姓名存到一個變量中,并向該用戶顯示一條消息。顯示的消息應非常簡單,如“Hello ...
    她即我命閱讀 3,143評論 0 5