行为设计模式---访问者模式(Visitor)

本文深入探讨了访问者模式的概念、优点、缺点,并通过C++代码实例展示了如何实现访问者模式,包括定义接口、抽象类和具体实现,以及如何在实际应用中使用访问者模式进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

访问者模式: 封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作

首先我们拥有一个由许多对象构成的对象结构,这些对象的类(Book)都拥有一个accept方法用来接受访问者对象;
访问者(IBookVisitor)是一个接口,它拥有一个visit方法,
这个方法对访问到的对象结构中不同类型的元素作出不同的反应;
在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,
在每一个元素的accept方法中回调访问者的visit方法,从而使访问者得以处理对象结构的每一个元素。
我们可以针对对象结构设计不同的实在的访问者类来完成不同的操作。

优点:
(1)访问者模式使得增加新的操作变得很容易。
如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。
而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易。
(2)访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中

缺点:
(1)访问者角色不适合具体元素角色经常发生变化的情况。(.e.g 增加新具体元素类,访问者接口就需要改变了)
(2)访问者角色要执行与元素角色相关的操作,就必须让元素角色将自己内部属性暴露出来,这就破坏了元素角色的封装性。
访问者和被访问的对象的耦合性很大

#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;

class Book;
class IBookVisitor
{
public:
        virtual void visit(Book *book) = 0;
        virtual ~IBookVisitor() {}
};

class IBook
{
public:
        virtual void accept(IBookVisitor *visitor) = 0;
        virtual ~IBook() { }
};

class Book : public IBook
{
public:
        Book(string name) : name_(name)
        {}
        string getName() const
        {
                return name_;
        }
        void accept(IBookVisitor *visitor)
        {
                visitor->visit(this);
        }

private:
        string name_;
};

class Library : public IBook
{
public:
        Library()
        {
                char name[32] = "";
                IBook *book = NULL;
                for (int i = 0; i < 10; ++i)
                {
                        sprintf(name, "Book %d", i);
                        book = new Book(name);
                        pool.push_back(book);
                }
        }
        ~Library()
        {
                int size = pool.size();
                for (int i = 0; i < size; ++i)
                {
                        delete pool[i];
                        pool[i] = NULL;
                }
                pool.clear();
        }
        void accept(IBookVisitor *visitor)
        {
                for (vector<IBook *>::iterator it = pool.begin(); it != pool.end(); ++it)
                        (*it)->accept(visitor);
        }

private:
        vector<IBook *> pool;
};

class Student : public IBookVisitor
{
public:
        void visit(Book *book)
        {
                cout << "Visiting " << book->getName() << endl;
        }
};

int main()
{
        Student student;
        Library library;
        library.accept(&student);

        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值