Как работает двойная отправка в шаблоне «Посетитель»?

Я изучал другие вопросы, связанные с шаблоном посетителя, но не мог понять реализацию двойной отправки в шаблоне посетителя.

Перейдите по ссылке Шаблон посетителя.

Как работает двойная отправка в шаблоне «Посетитель»?


person BOSS    schedule 20.07.2011    source источник
comment
Можно поконкретнее, что вам не понятно?   -  person jzd    schedule 20.07.2011
comment
Имхо, вы должны думать о двойной отправке как перегрузке функции во время выполнения, а не во время компиляции.   -  person dierre    schedule 20.07.2011


Ответы (4)


Метод accept объекта элемента получает объект посетителя и вызывает метод visit для объекта посетителя. Поскольку объект посетителя имеет несколько методов visit, в зависимости от типа элемента вызывается соответствующий метод visit. Здесь у нас есть два вызова (двойная отправка), которые определяют элемент и правильную операцию для элемента (в зависимости от его типа).

person salman.mirghasemi    schedule 20.07.2011

Однократное отправление

Единая отправка

Предположим, что Node — это класс интерфейса, а два подкласса — конкретные реализации интерфейса.

Если вы вызываете метод GenerateCode() для экземпляра узла, фактическая выполняемая операция зависит от типа узла. Это может быть метод либо в VariableRefNode, либо в AssignmentNode. То же самое, если вы позвоните PrettyPrint(). Таким образом, фактическое выполнение операции зависит от имени метода, который вы вызываете, и типа узла.

Двойная отправка

УзлыПосетители

На этот раз Node позволяет вам передать параметр типа NodeVisitor в его метод с именем Accept. В вашей программе, если вы вызываете Accept для экземпляра узла, фактическая выполняемая операция теперь зависит от типа узла (VariableRefNode или AssignmentNode) И типа посетителя. экземпляр, который вы передали в Accept (TypeCheckingVisitor или CodeGeneratingVisitor).

person Kaushalya    schedule 03.10.2012

Ну и соответствующая цитата из этой статьи:

Посетитель реализует «двойную отправку». Сообщения OO обычно проявляют «единую отправку» - выполняемая операция зависит от: имени запроса и типа получателя. При «двойной отправке» выполняемая операция зависит от: имени запроса и типа ДВУХ получателей (тип посетителя и тип элемента, который он посещает).

По сути, это означает, что разные посетители могут посещать один и тот же тип, а разные типы могут посещаться одним и тем же посетителем. Эффект именованной операции, выполняемой с использованием шаблона посетителя, может зависеть от посетителя и посетителя (двойная диспетчеризация).

person Bohemian♦    schedule 20.07.2011

Пример кода, который показывает двойную отправку:

import java.util.Arrays;
import java.util.List;

class Client {
    public static void main(String[] args) {
        List<Node> nodes = Arrays.asList(new NodeA(), new NodeB());
        List<NodeVisitor> visitors = Arrays.asList(new NodeVisitor1(), new NodeVisitor2());

        for (Node node : nodes) {
            for (NodeVisitor visitor : visitors) {
                node.accept(visitor);
            }
        }
    }
}

interface Node {
    void accept(NodeVisitor visitor);
}

interface NodeVisitor {
    void visit(Node node);
}

class NodeA implements Node {

    @Override
    public void accept(NodeVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String toString() {
        return "Node A";
    }
}

class NodeB implements Node {

    @Override
    public void accept(NodeVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String toString() {
        return "Node B";
    }
}

class NodeVisitor1 implements NodeVisitor {

    @Override
    public void visit(Node node) {
        System.out.println("Node visitor 1, node " + node);
    }
}

class NodeVisitor2 implements NodeVisitor {

    @Override
    public void visit(Node node) {
        System.out.println("Node visitor 2, node " + node);
    }
}

Результат:

Node visitor 1, node Node A
Node visitor 2, node Node A
Node visitor 1, node Node B
Node visitor 2, node Node B
person Vasil Yordanov    schedule 06.02.2019