作者: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