访问者是否可以修改它所访问的对象
当使用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