當使用Visitor Pattern時,visit(object)
方法是否可以更新或修改它所訪問的對象,或者只是簡單地假定只使用該對象執行某些計算並返回計算結果?訪問者是否可以修改它所訪問的對象
感謝
當使用Visitor Pattern時,visit(object)
方法是否可以更新或修改它所訪問的對象,或者只是簡單地假定只使用該對象執行某些計算並返回計算結果?訪問者是否可以修改它所訪問的對象
感謝
訪客模式並不意味着修改對象的狀態。相反,它的目的是實現特定功能。
一個範例將增加計算樹元素的功能,我在這個Case Study: Applied Design Patterns and Software Architecture中解釋了一個例子。
的CharacterVisitor
保持總的計數值訪問CustomCharacter
類具有以下結構:
/**
* Implements the Visitor pattern
*/
class CharacterVisitor
{
private int count = 0;
void visitCharacter(CustomCharacter customCharacter)
{
count++;
}
public int getResult()
{
return count;
}
}
的countCharacters()
功能,它實現了訪問者模式的邏輯:
/**
* Counts the words in the text by using the Iterator and Visitor patterns.
*/
int countCharacters()
{
CharacterVisitor characterVisitor = new CharacterVisitor();
CharacterIterator characterIterator =
new CharacterIterator(editorController.getCompositeBuilder());
characterIterator.first();
while(!characterIterator.isDone())
{
CustomCharacter customCharacter = characterIterator.getCurrent();
customCharacter.accept(characterVisitor);
characterIterator.next();
}
return characterVisitor.getResult();
}
注在這個例子中我也實現了Iterator pattern。我在案例研究中詳細介紹了更多細節。
你可以在這個github repository找到完整的代碼,我在這裏解釋了傳說中的書中提到的所有設計模式。
在以下示例中,郵件程序是「元素」,「訪問者」是傳遞到send()
的lambda表達式。
正如你可以在這裏看到的(在很多其他例子中)訪問者可以通過修改元素的內部狀態。也就是說,改變元素的內部狀態並不是必須的:訪問者可能會調用某些元素的方法來執行各種操作:將消息傳遞給另一個對象,運行計算並打印結果等
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
Mailer.send(mailer ->
mailer.from("[email protected]")
.to("[email protected]")
.body("what's up bud?")
);
}
}
class Mailer {
String fromStr;
String toStr;
String bodyStr;
public Mailer from(String from) {
this.fromStr = from;
return this;
}
public Mailer to(String to) {
this.toStr = to;
return this;
}
public Mailer body(String body) {
this.bodyStr = body;
return this;
}
public static void send(Consumer<Mailer> loader) {
Mailer mailer = new Mailer();
loader.accept(mailer);
System.out.println(mailer);
// ... send the email
}
@Override
public String toString() {
return "From: " + fromStr + "\n" +
"To: " + toStr + "\n" +
"Body: " + bodyStr;
}
}
我見過不改變物體參觀訪問者模式的所有實例。
但,據我瞭解的定義上Wikipedia給出的,它只是沒有定義什麼,遊客可以與被訪問對象做。
即使從Gang of Four(也在wiki文章)的定義不接觸該主題:
表示待上的對象 結構的元件執行的操作。訪客可以讓你定義一個新的操作,而不需要改變其操作元素的類別。
所以我想說,訪問者可以調用對象的任何訪問方法它訪問,因爲這不是訪問者模式的組成部分 - 訪問者模式只是描述這個對象是如何做訪問。
(And ...實際上,在訪問的目的是在圖表的節點上執行更改的情況下,我使用了訪問者模式。) –
訪問(對象)方法能夠更新或修改它所訪問的對象。也就是說,它只能更新或修改在該類上都是公共和非只讀的字段或屬性。或者,訪問方法可以使用對象公開的方法來更新或修改對象。
如果遵循這個無根據的規則,編譯器的許多操作將無法實現。 – EJP
也許我在答案中需要強調的一個澄清就是alfasin的回答所提到的:「改變元素的內部狀態並不是一個要求:可能是訪問者會調用某些元素的方法來完成所有種類的行爲「 –
也許當你寫'不想修改'你錯了。 – EJP