访问者可以修改它访问的对象

时间:2017-09-16 23:38:24

标签: java visitor

使用Visitor Pattern时,visit(object)方法可以更新或修改它访问的对象,还是仅仅假设只使用对象执行某些计算并返回计算结果?

由于

4 个答案:

答案 0 :(得分:3)

我见过的访客模式的

所有示例都不会更改所访问的对象。

据我理解Wikipedia上给出的定义,它只是未定义访问者可以对访问过的对象执行的操作。

即使来自Gang of Four的定义(也在维基文章中)也没有涉及该主题:

  

表示要对对象的元素执行的操作   结构体。访问者允许您定义新操作而无需更改   它运作的元素的类。

因此,我会说访问者可能在其访问的对象上调用任何可访问的方法,因为这不是访问者模式的一部分 - 访问者模式只是描述这些对象是如何可以访问

答案 1 :(得分:1)

在下面的示例中,邮件程序是“元素”,“访问者”是传递给send()的lambda表达式。

正如您在此处(以及许多其他示例中)所见,访问者可以修改元素的内部状态。也就是说,更改元素的内部状态不是必需的:访问者可能会调用某些元素的方法来执行各种操作:将消息传递给另一个对象,运行计算并打印到屏幕结果等。

import java.util.function.Consumer;

public class Main {

    public static void main(String[] args) {
        Mailer.send(mailer ->
            mailer.from("me@hotmail.com")
                    .to("you@hotmail.com")
                    .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;
    }
}

答案 2 :(得分:0)

  

访客模式并不意味着修改对象的状态。相反,其目的是实现特定功能

范例将添加计算树元素的功能,我在此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中找到完整的代码,其中我将解释传奇GOF一书中提到的所有设计模式。

答案 3 :(得分:0)

访问(对象)方法能够更新或修改它访问的对象。也就是说,它只能更新或修改该类的公共和非只读的字段或属性。或者,访问方法可以使用对象公开的公共方法来更新或修改对象。