訪問者模式:從介紹到實踐
百萬級高并發WebRTC流媒體服務器設計與開發
download:https://www.zxit666.com/1305/
01什么是訪客模式?
訪問者模式的定義如下,是指在不改變數據結構的情況下,提前定義新的操作。
封裝了一些作用于數據結構中元素的操作,可以在不改變數據結構的情況下定義作用于這些元素的新操作。
但在實際應用中,我發現有些例子并非如此。在一些例子中,沒有穩定的數據結構,但有穩定的算法。在亦舒看來,訪客模式是:固定不變的,開放可變的。
先說一個生活中的例子:一個科學家憑記憶面試。眾所周知,科學家在接受采訪時,肯定有一些程序上的限制。你是不可能隨便提問的。我們假設這個過程是:先問科學家的學校經歷,再談你的工作經歷,最后談你的科研成果。那么這個過程中固定的是什么呢?固定的是面試流程。有什么變化?改變的是,不同的記者可能會根據他們的學校經歷提出不同的問題。
按照我們之前的理解,訪客模式其實就是把不可改變的東西固定下來,把變化打開。然后我們可以抽象出科學家的采訪。
首先需要有一個Visitor類,定義了一些外部(記者)可以做的事情(提問學校經歷、工作經歷、科研成果)。
公共接口訪問者{
public void askSchoolExperience(字符串名);
public void askWorkExperience(字符串名);
public void askScienceAchievement(字符串名);
}
然后聲明一個XinhuaVisitor類來實現Visitor類,意思是新華社的一個記者(訪問者)要訪問科學家。
公共類XinhuaVisitor實現訪問者{
@覆蓋
public void askSchoolExperience(字符串名稱){
System.out.printf("請問%s:你在學校最大的成就是什么?n ",名稱);
}
@覆蓋
public void askWorkExperience(字符串名稱){
System.out.printf("請問%s:工作中最難忘的事是什么?n ",名稱);
}
@覆蓋
public void askScienceAchievement(字符串名稱){
System.out.printf("請問%s:最大的科研成果是什么?",姓名);
}
}
然后聲明一個科學家類,說明是科學家。科學家通過一個accept()方法接收記者(訪問者)的采訪申請并存儲。科學家定義了一種面試方法,把面試過程固定死。只有我教你問什么,我才會讓你(記者)提問。
公共類科學家{
私人訪問者訪問者;
私有字符串名稱;
私人科學家(){}
公共科學家(字符串名稱){
this.name = name
}
公共void接受(訪問者訪問者){
this.visitor =訪問者;
}
公開無效面試(){
system . out . println("-");
System.out.println(" -開始說學校經歷-");
visitor.askSchoolExperience(姓名);
System.out.println(" -開始說工作經歷-");
visitor.askWorkExperience(名稱);
System.out.println(" -開始說科研成果-");
visitor.askScienceAchievement(姓名);
}
}
最后,我們聲明一個場景類客戶端來模擬面試過程。
公共類客戶端{
公共靜態void main(String[] args) {
科學家楊=新科學家();
yang . accept(new XinhuaVisitor());
yang . interview();
}
}
操作的結果是:
-訪問開始
-開始談論學校經歷-
請問,楊振寧:你在學校最大的成就是什么?
-開始談論工作經歷-
請問楊振寧:你在工作中最難忘的觀點是什么?
-開始談論科研成果-
請問楊振寧:最大的科研成就是什么?
看到這里,大家對訪客模式的本質(固定不變,開放可變)有了更感性的認識。在這個例子中,不變的、固定的是面試過程。改變的是你可以問不同的問題。
一般來說,訪問者模式的類結構如下圖所示:
訪問者訪問者界面。訪問者定義訪問者可以做什么。這就需要你分析什么是可改變的,把這些可改變的內容抽象成一個訪問者接口方法,把它開放出來。被訪問者的信息實際上是通過訪問者的參數傳遞的。
具體訪問者。特定訪問者定義了特定類型訪問者的實現。對于新華社記者來說,他們更關心楊振寧的科學成就,所以提問時更傾向于挖掘成就。但對于青年報記者來說,他們的讀者是青少年,他們更關注楊振寧在學習和工作中的精神。
元素具體元素。這指的是特定的被訪問的類,在我們的例子中,是科學家類。一般情況下,我們會提供一個accept()方法來接收訪問者參數,這將相當于接受它的模型應用。然而,這種方法不是必需的。只要能得到visitor對象,就可以定義這個參數傳遞。
對于訪問者模式,最重要的是訪問者、具體訪問者和元素。Visitor和ConcreteVisitor定義了訪問者具體能做什么,被訪問者的參數通過參數傳遞給訪問者。元素通過各種方法獲取被訪問的對象,通常是通過accept()方法,但這不是絕對的。
應該注意的是,我們對設計模式的研究側重于理解類之間的關系以及它們所傳達的信息。至于如何傳遞,是通過accept()方法還是通過構造函數,都不是重點。