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

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

问题描述

我在blog中看到了访问者模式的引用,但我不得不承认,我根本就不知道。我阅读了维基百科文章的模式,我了解其机制,但我仍然感到困惑当我使用它。

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.

由于刚刚真正拥有装饰器模式的人,现在正在看到它的用途, d喜欢直观地了解这个看似方便的模式。

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!\n"; }

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

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

但是,通过这种方式,每次要添加操作时,都必须修改界面每一级的层次结构。现在,假设您对原始界面感到满意,并希望对其进行最少的修改。

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中的访客类),它具有层次结构中每个类的一个方法:

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!\n"; }

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

现在,您有一种方法可以添加操作而不再修改层次结构。
这是它的工作原理:

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天全站免登陆