什么时候应该使用访问者设计模式? [英] When should I use the Visitor Design Pattern?

查看:18
本文介绍了什么时候应该使用访问者设计模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在博客中看到对访问者模式的引用,但我必须承认,我就是不明白.我阅读了 维基百科文章关于模式,我了解它的机制,但我仍然对当我使用它时.

I keep seeing references to the visitor pattern in blogs but I've got to admit, I just don't get it. I read the wikipedia article for the pattern and I understand its mechanics but I'm still confused as to when I'd use it.

作为最近才真正获得装饰器模式并且现在在任何地方都能看到它的用途的人,我也希望能够真正直观地理解这种看似方便的模式.

As someone who just recently really got the decorator pattern and is now seeing uses for it absolutely everywhere I'd like to be able to really understand intuitively this seemingly handy pattern as well.

推荐答案

我对访问者模式不是很熟悉.让我们看看我是否做对了.假设你有一个动物等级

I'm not very familiar with the Visitor pattern. Let's see if I got it right. Suppose you have a hierarchy of animals

class Animal {  };
class Dog: public Animal {  };
class Cat: public Animal {  };

(假设它是一个具有完善接口的复杂层次结构.)

(Suppose it is a complex hierarchy with a well-established interface.)

现在我们要向层次结构添加一个新操作,即我们希望每个动物都发出自己的声音.就层次结构而言如此简单,您可以使用直接多态来实现:

Now we want to add a new operation to the hierarchy, namely we want each animal to make its sound. As far as the hierarchy is this simple, you can do it with straight polymorphism:

class Animal
{ public: virtual void makeSound() = 0; };

class Dog : public Animal
{ public: void makeSound(); };

void Dog::makeSound()
{ std::cout << "woof!
"; }

class Cat : public Animal
{ public: void makeSound(); };

void Cat::makeSound()
{ std::cout << "meow!
"; }

但是以这种方式进行,每次要添加操作时,您都必须修改层次结构中每个类的接口.现在,假设您对原始界面感到满意,并且希望对其进行尽可能少的修改.

But proceeding in this way, each time you want to add an operation you must modify the interface to every single class of the hierarchy. Now, suppose instead that you are satisfied with the original interface, and that you want to make the fewest possible modifications to it.

访问者模式允许您在合适的类中移动每个新操作,并且您只需要扩展层次结构的接口一次.我们开始做吧.首先,我们定义一个抽象操作(GoF 中的Visitor"类),它有一个方法层次结构中的每个类:

The Visitor pattern allows you to move each new operation in a suitable class, and you need to extend the hierarchy's interface only once. Let's do it. First, we define an abstract operation (the "Visitor" class in GoF) which has a method for every class in the hierarchy:

class Operation
{
public:
    virtual void hereIsADog(Dog *d) = 0;
    virtual void hereIsACat(Cat *c) = 0;
};

然后,我们修改层次结构以接受新的操作:

Then, we modify the hierarchy in order to accept new operations:

class Animal
{ public: virtual void letsDo(Operation *v) = 0; };

class Dog : public Animal
{ public: void letsDo(Operation *v); };

void Dog::letsDo(Operation *v)
{ v->hereIsADog(this); }

class Cat : public Animal
{ public: void letsDo(Operation *v); };

void Cat::letsDo(Operation *v)
{ v->hereIsACat(this); }

最后,我们实现了实际操作,既不修改猫也不修改狗:

Finally, we implement the actual operation, without modifying neither Cat nor Dog:

class Sound : public Operation
{
public:
    void hereIsADog(Dog *d);
    void hereIsACat(Cat *c);
};

void Sound::hereIsADog(Dog *d)
{ std::cout << "woof!
"; }

void Sound::hereIsACat(Cat *c)
{ std::cout << "meow!
"; }

现在您可以在不修改层次结构的情况下添加操作.这是它的工作原理:

Now you have a way to add operations without modifying the hierarchy anymore. Here is how it works:

int main()
{
    Cat c;
    Sound theSound;
    c.letsDo(&theSound);
}

这篇关于什么时候应该使用访问者设计模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆