设计模式23 - 访问者模式

作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

访问者模式

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

使用场景

  • 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

优缺点

  • 优点:
    1、符合单一职责原则。
    2、优秀的扩展性。
    3、灵活性。

  • 缺点:
    1、具体元素对访问者公布细节,违反了迪米特原则。
    2、具体元素变更比较困难。
    3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

注意事项

访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器

UML结构图

在这里插入图片描述

代码实现

father.h
创建抽象类 - 访问者、计算机部件

#include <iostream>
using namespace std;

class Computer;
class Mouse;
class Keyboard;
class Monitor;

class ComputerPartVisitor   //基类-访问者
{
public:
    ComputerPartVisitor() {}
    virtual ~ComputerPartVisitor() {}

    virtual void visit(Computer *computer) = 0;
    virtual void visit(Mouse *mouse) = 0;
    virtual void visit(Keyboard *keyboard) = 0;
    virtual void visit(Monitor *monitor) = 0;
};

class ComputerPart  //基类-计算机部件
{
public:
    ComputerPart() {}
    virtual ~ComputerPart() {}

    virtual void accept(ComputerPartVisitor *computerPartVisitor) = 0;
    virtual string getString() = 0;
};

son.h
创建实体类 - 键盘、鼠标、显示屏、计算机、计算机访问者
实现主要功能:计算机访问者中可以根据访问对象的不同,执行不同对象的操作

#include "father.h"
#include <vector>
#include <string>

class Keyboard: public ComputerPart //子类-键盘
{
public:
    void accept(ComputerPartVisitor *computerPartVisitor)
    {
        computerPartVisitor->visit(this);
    }

    string getString() { return "Displaying Keyboard"; }
};

class Monitor: public ComputerPart  //子类-显示器
{
public:
    void accept(ComputerPartVisitor *computerPartVisitor)
    {
        computerPartVisitor->visit(this);
    }

    string getString() { return "Displaying Monitor"; }
};

class Mouse: public ComputerPart    //子类-鼠标
{
public:
    void accept(ComputerPartVisitor *computerPartVisitor)
    {
        computerPartVisitor->visit(this);
    }

    string getString() { return "Displaying Mouse"; }
};

class Computer: public ComputerPart //子类-计算机(包含显示器、鼠标、键盘)
{
public:
    Computer()
    {
        ComputerPart *keyboard = new Keyboard();
        ComputerPart *monitor = new Monitor();
        ComputerPart *mouse = new Mouse();
        vector.push_back(keyboard);
        vector.push_back(monitor);
        vector.push_back(mouse);
    }

    void accept(ComputerPartVisitor *computerPartVisitor)
    {
        for(size_t i = 0; i < vector.size(); i++)
        {
            vector.at(i)->accept(computerPartVisitor);
        }
        computerPartVisitor->visit(this);
    }

    string getString() { return "Displaying Computer"; }

private:
    std::vector<ComputerPart *> vector;
};

class ComputerPartDisplayVisitor: public ComputerPartVisitor    //子类-计算机访问者
{
public:
    void visit(Computer *computer)
    {
        cout << computer->getString() << endl;
    }

    void visit(Mouse *mouse)
    {
        cout << mouse->getString() << endl;
    }

    void visit(Keyboard *keyboard)
    {
        cout << keyboard->getString() << endl;
    }

    void visit(Monitor *monitor)
    {
        cout << monitor->getString() << endl;
    }
};

main.cpp
实例应用 - 使用 ComputerPartDisplayVisitor 来显示 Computer 的组成部分

#include "son.h"

int main()
{
    ComputerPartDisplayVisitor *cp = new ComputerPartDisplayVisitor();
    ComputerPart *computer = new Computer();
    ComputerPart *mouse = new Mouse();
    ComputerPart *keyboard = new Keyboard();
    ComputerPart *monitor = new Monitor();

    computer->accept(cp);
    cout << endl;

    mouse->accept(cp);
    keyboard->accept(cp);
    monitor->accept(cp);

    return 0;
}

运行结果:
Displaying Keyboard
Displaying Monitor
Displaying Mouse
Displaying Computer

Displaying Mouse
Displaying Keyboard
Displaying Monitor
发布了61 篇原创文章 · 获赞 218 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34139994/article/details/95641837