热门问题
时间线
聊天
视角

訪問者模式

来自维基百科,自由的百科全书

访问者模式
Remove ads

訪問者模式(visitor pattern),是一種將算法與對象結構分離的軟件設計模式[2]。訪問者模式使得在傳統的單分派語言(如SmalltalkJavaC++)中模擬雙分派英語Double dispatch技術。對於支持多分派的語言(如CLOS),訪問者模式已經在其語言特性之中了,而不再重要。

Thumb
訪問者模式用統一建模語言(UML)來表示。[1](p. 381)

概述

訪問者模式是一個由許多對象構成的對象結構,這些對象的都擁有一個accept方法用來接受訪問者對象;訪問者是一個接口,它有一個visit方法,這個方法對訪問到的對象結構中不同類型的元素作出相應的動作;在對象結構的訪問過程中,visit方法遍歷整個對象結構,對每一個元素都實施accept方法,在每一個元素的accept方法中回調訪問者的visit方法,從而使訪問者得以處理對象結構的每一個元素。我們可以針對對象結構設計不同的實在的訪問者類來完成不同的操作。

例子

Java

Thumb

Java的例子:

import java.util.List;

interface CarElement {
    void accept(CarElementVisitor visitor);
}

interface CarElementVisitor {
    void visit(Body body);
    void visit(Car car);
    void visit(Engine engine);
    void visit(Wheel wheel);
}

class Wheel implements CarElement {
    private final String name;
    public Wheel(final String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    @Override
    public void accept(CarElementVisitor visitor) {
        visitor.visit(this);
    }
}

class Body implements CarElement {
    @Override
    public void accept(CarElementVisitor visitor) {
        visitor.visit(this);
    }
}

class Engine implements CarElement {
    @Override
    public void accept(CarElementVisitor visitor) {
        visitor.visit(this);
    }
}

class Car implements CarElement {
    private final List<CarElement> elements;
    public Car() {
        this.elements = List.of(
            new Wheel("front left"), new Wheel("front right"),
            new Wheel("back left"), new Wheel("back right"),
            new Body(), new Engine()
        );
    }
    @Override
    public void accept(CarElementVisitor visitor) {
        for (CarElement element : elements) {
            element.accept(visitor);
        }
        visitor.visit(this);
    }
}

class CarElementDoVisitor implements CarElementVisitor {
    @Override
    public void visit(Body body) {
        System.out.println("Moving my body");
    }
    @Override
    public void visit(Car car) {
        System.out.println("Starting my car");
    }
    @Override
    public void visit(Wheel wheel) {
        System.out.println("Kicking my " + wheel.getName() + " wheel");
    }
    @Override
    public void visit(Engine engine) {
        System.out.println("Starting my engine");
    }
}

class CarElementPrintVisitor implements CarElementVisitor {
    @Override
    public void visit(Body body) {
        System.out.println("Visiting body");
    }
    @Override
    public void visit(Car car) {
        System.out.println("Visiting car");
    }
    @Override
    public void visit(Engine engine) {
        System.out.println("Visiting engine");
    }
    @Override
    public void visit(Wheel wheel) {
        System.out.println("Visiting " + wheel.getName() + " wheel");
    }
}

public class VisitorDemo {
    public static void main(final String[] args) {
        Car car = new Car();
        car.accept(new CarElementPrintVisitor());
        car.accept(new CarElementDoVisitor());
    }
}

輸出:

Visiting front left wheel
Visiting front right wheel
Visiting back left wheel
Visiting back right wheel
Visiting body
Visiting engine
Visiting car
Kicking my front left wheel
Kicking my front right wheel
Kicking my back left wheel
Kicking my back right wheel
Moving my body
Starting my engine
Starting my car
Remove ads

Python

Python的例子:

from abc import ABCMeta, abstractmethod

class CarElement(metaclass=ABCMeta):
    @abstractmethod
    def accept(self, visitor): pass

class CarElementVisitor(metaclass=ABCMeta):
    @abstractmethod
    def visitBody(self, element): pass
    @abstractmethod
    def visitEngine(self, element): pass
    @abstractmethod
    def visitWheel(self, element): pass
    @abstractmethod
    def visitCar(self, element): pass

class Body(CarElement):
    def accept(self, visitor):
        visitor.visitBody(self)

class Engine(CarElement):
    def accept(self, visitor):
        visitor.visitEngine(self)

class Wheel(CarElement):
    def __init__(self, name):
        self.name = name
    def accept(self, visitor):
        visitor.visitWheel(self)

class Car(CarElement):
    def __init__(self):
        self.elements = [
            Wheel("front left"), Wheel("front right"),
            Wheel("back left"), Wheel("back right"),
            Body(), Engine()]
    def accept(self, visitor):
        for element in self.elements:
            element.accept(visitor)
        visitor.visitCar(self)

class CarElementDoVisitor(CarElementVisitor):
    def visitBody(self, body):
        print("Moving my body.")
    def visitCar(self, car):
        print("Starting my car.")
    def visitWheel(self, wheel):
        print("Kicking my {} wheel.".format(wheel.name))
    def visitEngine(self, engine):
        print("Starting my engine.")

class CarElementPrintVisitor(CarElementVisitor):
    def visitBody(self, body):
        print("Visiting body.")
    def visitCar(self, car):
        print("Visiting car.")
    def visitWheel(self, wheel):
        print("Visiting {} wheel.".format(wheel.name))
    def visitEngine(self, engine):
        print("Visiting engine.")

其用例:

>>> car = Car()
>>> car.accept(CarElementPrintVisitor())
Visiting front left wheel.
Visiting front right wheel.
Visiting back left wheel.
Visiting back right wheel.
Visiting body.
Visiting engine.
Visiting car.
>>> car.accept(CarElementDoVisitor())
Kicking my front left wheel.
Kicking my front right wheel.
Kicking my back left wheel.
Kicking my back right wheel.
Moving my body.
Starting my engine.
Starting my car.
Remove ads

參考條目

引用

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads