Подтвердить что ты не робот

Как работает двойная диспетчеризация в шаблоне посетителей?

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

Пожалуйста, обратитесь к ссылке Шаблон посетителя

Как работает двойная диспетчеризация в шаблоне посетителя?

4b9b3361

Ответ 1

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

Ответ 2

Single-диспетчерская

Single dispatch

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

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

Дважды диспетчерская

NodesVisitors

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

Ответ 3

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

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

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

Ответ 4

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

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