具有多个参数的访客模式

时间:2014-07-31 07:30:04

标签: c++ oop design-patterns

是否可以实现访问者模式:

  1. 可以在接受者上使用多个访问者。

  2. 添加新访问者时,接受者不得更改。

  3. 访客可能必须接收参数,参与者的参数数量和类型也不同。

  4. 一个示例是Shape层次结构类和可以对形状执行的操作。如果操作不必接收任何参数,那么每个操作都可以是访问者并从Visitor类继承,并且每个形状都将实现accept方法:

    void SomeShape::accept(Visitor* visitor)
    {
        visitor->visit(*this);
    }
    

    但是,有没有办法使用访问者模式,以防每个访问者需要接收其他参数?有什么好的选择吗?

2 个答案:

答案 0 :(得分:4)

您需要将其他参数存储在访问者本身中。它们通常在构造函数中传递。这就是所谓的 reification (“make real”):带参数的函数调用现在是一个对象,代表函数调用,并存储参数。你现在可以在不看内部的情况下传递这个对象,这就是我们想要的。

您的accept函数应该使用Visitor const&,以便您可以传递临时值,这很方便:

pShape->accept(SnapToPoint(x, y));

SnapToPoint类看起来像这样:

struct SnapToPoint : Visitor {
    SnapToPoint(float x, float y) : _point(x, y) {}

    void visit(Circle   &c) const override { /* Use _point on c */ }
    void visit(Triangle &t) const override { /* Use _point on t */ }
    void visit(Square   &s) const override { /* Use _point on s */ }

private:
    Point _point;
};

编辑:为了响应下面的依赖注入需求,访问者工厂的示例:

struct ShapeOperationFactory {
    virtual std::unique_ptr<Visitor> snapToPoint(float x, float y) const = 0;
};

struct MyShapeOpFactory : ShapeOperationFactory {
    std::unique_ptr<Visitor> snapToPoint(float x, float y) const override {
        return std::unique_ptr<Visitor>(new SnapToPoint(x, y));
    }
};

这会被称为:

ShapeOperationFactory *pFactory = /* Get a factory */;
pShape->accept(pFactory->snapToPoint(4.0f, 7.0f));

看到它正常工作here。请注意,这次我必须通过Visitor std::unique_ptr实例,因为工厂是通用的。

编辑2:刷新了我对临时生活的记忆。我已将accept函数回滚到Visitor const&,请参阅结果here

答案 1 :(得分:0)

你正在做出决定。

在访问者模式中没有办法做你想要的,如果是的话它将不会有更多的访问者模式,因为它的主要职责是定义一组函数来执行一堆数据保持抽象足够高,以避免Acceptor中的具体类型识别。

可能仍然拥有你要求的东西:例如你可以在访问者本身内保留一些状态变量/(联合),因此在其上执行accept会产生不同的结果基于具体Visitor实例的内部状态。